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 /* Constants used by FunctionalTest20_21 */
   9842 const GLuint FunctionalTest20_21::m_n_shared_contexts				   = 4;
   9843 const GLuint FunctionalTest20_21::m_fragment_stage_index			   = 0;
   9844 const GLuint FunctionalTest20_21::m_geometry_stage_index			   = 1;
   9845 const GLuint FunctionalTest20_21::m_tesselation_control_stage_index	= 2;
   9846 const GLuint FunctionalTest20_21::m_tesselation_evaluation_stage_index = 3;
   9847 const GLuint FunctionalTest20_21::m_vertex_stage_index				   = 4;
   9848 
   9849 /** Set subroutine indices, indices are taken from one of two sets according to provided <bit_field>
   9850  *
   9851  * @param bit_field          Selects source of of index for each stage
   9852  * @param subroutine_indices Array of two indices sets
   9853  **/
   9854 void FunctionalTest20_21::subroutineUniformSet::set(GLuint bit_field, const subroutineUniformSet subroutine_indices[2])
   9855 {
   9856 	GLuint vertex_stage					= ((bit_field & (0x01 << 0)) >> 0);
   9857 	GLuint tesselation_control_stage	= ((bit_field & (0x01 << 1)) >> 1);
   9858 	GLuint tesselation_evaluation_stage = ((bit_field & (0x01 << 2)) >> 2);
   9859 	GLuint geometry_stage				= ((bit_field & (0x01 << 3)) >> 3);
   9860 	GLuint fragment_stage				= ((bit_field & (0x01 << 4)) >> 4);
   9861 
   9862 	m_vertex_shader_stage = subroutine_indices[vertex_stage].m_vertex_shader_stage;
   9863 	m_tesselation_control_shader_stage =
   9864 		subroutine_indices[tesselation_control_stage].m_tesselation_control_shader_stage;
   9865 	m_tesselation_evaluation_shader_stage =
   9866 		subroutine_indices[tesselation_evaluation_stage].m_tesselation_evaluation_shader_stage;
   9867 	m_geometry_shader_stage = subroutine_indices[geometry_stage].m_geometry_shader_stage;
   9868 	m_fragment_shader_stage = subroutine_indices[fragment_stage].m_fragment_shader_stage;
   9869 }
   9870 
   9871 /** Negated comparison of two sets
   9872  *
   9873  * @param arg Instance that will be compared to this
   9874  *
   9875  * @return false when both objects are equal, true otherwise
   9876  **/
   9877 bool FunctionalTest20_21::subroutineUniformSet::operator!=(const subroutineUniformSet& arg) const
   9878 {
   9879 	if ((arg.m_vertex_shader_stage != m_vertex_shader_stage) ||
   9880 		(arg.m_tesselation_control_shader_stage != m_tesselation_control_shader_stage) ||
   9881 		(arg.m_tesselation_evaluation_shader_stage != m_tesselation_evaluation_shader_stage) ||
   9882 		(arg.m_geometry_shader_stage != m_geometry_shader_stage) ||
   9883 		(arg.m_fragment_shader_stage != m_fragment_shader_stage))
   9884 	{
   9885 		return true;
   9886 	}
   9887 
   9888 	return false;
   9889 }
   9890 
   9891 /** Constructor.
   9892  *
   9893  *  @param context Rendering context.
   9894  *
   9895  **/
   9896 FunctionalTest20_21::FunctionalTest20_21(deqp::Context& context)
   9897 	: TestCase(context, "multiple_contexts",
   9898 			   "Verifies that shader uniforms are preserved when rendering context is switched.")
   9899 {
   9900 	for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i)
   9901 	{
   9902 		m_program_pipelines[i] = 0;
   9903 	}
   9904 
   9905 	for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   9906 	{
   9907 		m_shared_contexts[i] = 0;
   9908 	}
   9909 }
   9910 
   9911 /** Deinitializes all GL objects that may have been created during
   9912  *  test execution.
   9913  **/
   9914 void FunctionalTest20_21::deinit()
   9915 {
   9916 	/* GL entry points */
   9917 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   9918 
   9919 	for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i)
   9920 	{
   9921 		if (0 != m_program_pipelines[i])
   9922 		{
   9923 			gl.deleteProgramPipelines(1, &m_program_pipelines[i]);
   9924 			m_program_pipelines[i] = 0;
   9925 		}
   9926 	}
   9927 
   9928 	for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   9929 	{
   9930 		if (0 != m_shared_contexts[i])
   9931 		{
   9932 			delete m_shared_contexts[i];
   9933 			m_shared_contexts[i] = 0;
   9934 		}
   9935 	}
   9936 
   9937 	m_context.getRenderContext().makeCurrent();
   9938 }
   9939 
   9940 /** Executes test iteration.
   9941  *
   9942  *  @return Returns STOP
   9943  */
   9944 tcu::TestNode::IterateResult FunctionalTest20_21::iterate()
   9945 {
   9946 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   9947 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   9948 	{
   9949 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   9950 	}
   9951 
   9952 	/* Test cases, values stored here are used as bit fields */
   9953 	static const GLuint test_cases[][m_n_shared_contexts + 1] = {
   9954 		{ 0, 1, 2, 3, 4 },		{ 1, 2, 3, 4, 0 },		{ 2, 3, 4, 0, 1 },		{ 3, 4, 0, 1, 2 },
   9955 		{ 4, 0, 1, 2, 3 },		{ 27, 28, 29, 30, 31 }, { 28, 29, 30, 31, 27 }, { 29, 30, 31, 27, 28 },
   9956 		{ 30, 31, 27, 28, 29 }, { 31, 27, 28, 29, 30 },
   9957 	};
   9958 	static const GLuint n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
   9959 
   9960 	/* Prepare contexts */
   9961 	initSharedContexts();
   9962 
   9963 	/* Test result */
   9964 	bool result = true;
   9965 
   9966 	/* Program pointers */
   9967 	Utils::program* program_pointers[5];
   9968 
   9969 	/* Test monolithic program */
   9970 	{
   9971 		/* Prepare program */
   9972 		Utils::program program(m_context);
   9973 
   9974 		program_pointers[m_fragment_stage_index] = &program;
   9975 
   9976 		prepareProgram(program_pointers, false);
   9977 
   9978 		/* Execute test */
   9979 		if (false == testProgram(program_pointers, false, test_cases, n_test_cases))
   9980 		{
   9981 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   9982 												<< "Last error message was caused by monolithic program."
   9983 												<< tcu::TestLog::EndMessage;
   9984 
   9985 			result = false;
   9986 		}
   9987 	}
   9988 
   9989 	/* Test separable programs */
   9990 	if (true == m_context.getContextInfo().isExtensionSupported("GL_ARB_separate_shader_objects"))
   9991 	{
   9992 		/* Prepare programs */
   9993 		Utils::program vertex_program(m_context);
   9994 		Utils::program tesselation_control_program(m_context);
   9995 		Utils::program tesselation_evaluation_program(m_context);
   9996 		Utils::program geometry_program(m_context);
   9997 		Utils::program fragment_program(m_context);
   9998 
   9999 		program_pointers[m_fragment_stage_index]			   = &fragment_program;
   10000 		program_pointers[m_geometry_stage_index]			   = &geometry_program;
   10001 		program_pointers[m_tesselation_control_stage_index]	= &tesselation_control_program;
   10002 		program_pointers[m_tesselation_evaluation_stage_index] = &tesselation_evaluation_program;
   10003 		program_pointers[m_vertex_stage_index]				   = &vertex_program;
   10004 
   10005 		prepareProgram(program_pointers, true);
   10006 
   10007 		/* Execute test */
   10008 		if (false == testProgram(program_pointers, true, test_cases, n_test_cases))
   10009 		{
   10010 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   10011 												<< "Last error message was caused by separable program."
   10012 												<< tcu::TestLog::EndMessage;
   10013 			result = false;
   10014 		}
   10015 	}
   10016 
   10017 	/* All done */
   10018 	if (true == result)
   10019 	{
   10020 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   10021 	}
   10022 	else
   10023 	{
   10024 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   10025 	}
   10026 
   10027 	return tcu::TestNode::STOP;
   10028 }
   10029 
   10030 /** Query state of subroutine uniforms of current program/pipeline
   10031  *
   10032  * @param set Storage for results
   10033  **/
   10034 void FunctionalTest20_21::captureCurrentSubroutineSet(subroutineUniformSet& set)
   10035 {
   10036 	/* GL entry points */
   10037 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10038 
   10039 	/* Fragment */
   10040 	gl.getUniformSubroutineuiv(GL_FRAGMENT_SHADER, m_subroutine_uniform_locations.m_fragment_shader_stage,
   10041 							   &set.m_fragment_shader_stage);
   10042 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv");
   10043 
   10044 	/* Geometry */
   10045 	gl.getUniformSubroutineuiv(GL_GEOMETRY_SHADER, m_subroutine_uniform_locations.m_geometry_shader_stage,
   10046 							   &set.m_geometry_shader_stage);
   10047 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv");
   10048 
   10049 	/* Tess ctrl */
   10050 	gl.getUniformSubroutineuiv(GL_TESS_CONTROL_SHADER,
   10051 							   m_subroutine_uniform_locations.m_tesselation_control_shader_stage,
   10052 							   &set.m_tesselation_control_shader_stage);
   10053 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv");
   10054 
   10055 	/* Tess eval */
   10056 	gl.getUniformSubroutineuiv(GL_TESS_EVALUATION_SHADER,
   10057 							   m_subroutine_uniform_locations.m_tesselation_evaluation_shader_stage,
   10058 							   &set.m_tesselation_evaluation_shader_stage);
   10059 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv");
   10060 
   10061 	/* Vertex */
   10062 	gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_subroutine_uniform_locations.m_vertex_shader_stage,
   10063 							   &set.m_vertex_shader_stage);
   10064 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformSubroutineuiv");
   10065 }
   10066 
   10067 /** Get shaders' source code
   10068  *
   10069  * @param out_vertex_shader_code                 Vertex source code
   10070  * @param out_tesselation_control_shader_code    Tess ctrl source code
   10071  * @param out_tesselation_evaluation_shader_code Tess eval source code
   10072  * @param out_geometry_shader_code               Geometry source code
   10073  * @param out_fragment_shader_code               Fragment source code
   10074  **/
   10075 void FunctionalTest20_21::getShaders(const glw::GLchar*& out_vertex_shader_code,
   10076 									 const glw::GLchar*& out_tesselation_control_shader_code,
   10077 									 const glw::GLchar*& out_tesselation_evaluation_shader_code,
   10078 									 const glw::GLchar*& out_geometry_shader_code,
   10079 									 const glw::GLchar*& out_fragment_shader_code)
   10080 {
   10081 	static const GLchar* vertex_shader_code = "#version 400 core\n"
   10082 											  "#extension GL_ARB_shader_subroutine : require\n"
   10083 											  "\n"
   10084 											  "precision highp float;\n"
   10085 											  "\n"
   10086 											  "// Subroutine type\n"
   10087 											  "subroutine vec4 routine_type(in vec4 left, in vec4 right);\n"
   10088 											  "\n"
   10089 											  "// Subroutine definition\n"
   10090 											  "subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n"
   10091 											  "{\n"
   10092 											  "    return left + right;\n"
   10093 											  "}\n"
   10094 											  "\n"
   10095 											  "subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n"
   10096 											  "{\n"
   10097 											  "    return left * right;\n"
   10098 											  "}\n"
   10099 											  "\n"
   10100 											  "// Sub routine uniform\n"
   10101 											  "subroutine uniform routine_type routine;\n"
   10102 											  "\n"
   10103 											  "// Input data\n"
   10104 											  "uniform vec4 uni_vs_left;\n"
   10105 											  "uniform vec4 uni_vs_right;\n"
   10106 											  "\n"
   10107 											  "// Output\n"
   10108 											  "out vec4 vs_tcs_result;\n"
   10109 											  "\n"
   10110 											  "void main()\n"
   10111 											  "{\n"
   10112 											  "    vs_tcs_result = routine(uni_vs_left, uni_vs_right);\n"
   10113 											  "}\n"
   10114 											  "\n";
   10115 
   10116 	static const GLchar* tesselation_control_shader_code =
   10117 		"#version 400 core\n"
   10118 		"#extension GL_ARB_shader_subroutine : require\n"
   10119 		"\n"
   10120 		"precision highp float;\n"
   10121 		"\n"
   10122 		"layout(vertices = 1) out;\n"
   10123 		"\n"
   10124 		"// Subroutine type\n"
   10125 		"subroutine vec4 routine_type(in vec4 left, in vec4 right);\n"
   10126 		"\n"
   10127 		"// Subroutine definition\n"
   10128 		"subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n"
   10129 		"{\n"
   10130 		"    return left + right;\n"
   10131 		"}\n"
   10132 		"\n"
   10133 		"subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n"
   10134 		"{\n"
   10135 		"    return left * right;\n"
   10136 		"}\n"
   10137 		"\n"
   10138 		"// Sub routine uniform\n"
   10139 		"subroutine uniform routine_type routine;\n"
   10140 		"\n"
   10141 		"// Input data\n"
   10142 		"uniform vec4 uni_tcs_left;\n"
   10143 		"uniform vec4 uni_tcs_right;\n"
   10144 		"\n"
   10145 		"in vec4 vs_tcs_result[];\n"
   10146 		"\n"
   10147 		"// Output\n"
   10148 		"out vec4 tcs_tes_result[];\n"
   10149 		"\n"
   10150 		"void main()\n"
   10151 		"{\n"
   10152 		"    gl_TessLevelOuter[0] = 1.0;\n"
   10153 		"    gl_TessLevelOuter[1] = 1.0;\n"
   10154 		"    gl_TessLevelOuter[2] = 1.0;\n"
   10155 		"    gl_TessLevelOuter[3] = 1.0;\n"
   10156 		"    gl_TessLevelInner[0] = 1.0;\n"
   10157 		"    gl_TessLevelInner[1] = 1.0;\n"
   10158 		"\n"
   10159 		"    tcs_tes_result[gl_InvocationID] = routine(uni_tcs_left, uni_tcs_right) + vs_tcs_result[gl_InvocationID];\n"
   10160 		"}\n"
   10161 		"\n";
   10162 
   10163 	static const GLchar* tesselation_evaluation_shader_code =
   10164 		"#version 400 core\n"
   10165 		"#extension GL_ARB_shader_subroutine : require\n"
   10166 		"\n"
   10167 		"precision highp float;\n"
   10168 		"\n"
   10169 		"layout(isolines, point_mode) in;\n"
   10170 		"\n"
   10171 		"// Subroutine type\n"
   10172 		"subroutine vec4 routine_type(in vec4 left, in vec4 right);\n"
   10173 		"\n"
   10174 		"// Subroutine definition\n"
   10175 		"subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n"
   10176 		"{\n"
   10177 		"    return left + right;\n"
   10178 		"}\n"
   10179 		"\n"
   10180 		"subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n"
   10181 		"{\n"
   10182 		"    return left * right;\n"
   10183 		"}\n"
   10184 		"\n"
   10185 		"// Sub routine uniform\n"
   10186 		"subroutine uniform routine_type routine;\n"
   10187 		"\n"
   10188 		"// Input data\n"
   10189 		"uniform vec4 uni_tes_left;\n"
   10190 		"uniform vec4 uni_tes_right;\n"
   10191 		"\n"
   10192 		"in vec4 tcs_tes_result[];\n"
   10193 		"\n"
   10194 		"// Output\n"
   10195 		"out vec4 tes_gs_result;\n"
   10196 		"\n"
   10197 		"void main()\n"
   10198 		"{\n"
   10199 		"    tes_gs_result = routine(uni_tes_left, uni_tes_right) + tcs_tes_result[0];\n"
   10200 		"}\n"
   10201 		"\n";
   10202 
   10203 	static const GLchar* geometry_shader_code =
   10204 		"#version 400 core\n"
   10205 		"#extension GL_ARB_shader_subroutine : require\n"
   10206 		"\n"
   10207 		"precision highp float;\n"
   10208 		"\n"
   10209 		"layout(points)                   in;\n"
   10210 		"layout(points, max_vertices = 1) out;\n"
   10211 		"\n"
   10212 		"// Subroutine type\n"
   10213 		"subroutine vec4 routine_type(in vec4 left, in vec4 right);\n"
   10214 		"\n"
   10215 		"// Subroutine definition\n"
   10216 		"subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n"
   10217 		"{\n"
   10218 		"    return left + right;\n"
   10219 		"}\n"
   10220 		"\n"
   10221 		"subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n"
   10222 		"{\n"
   10223 		"    return left * right;\n"
   10224 		"}\n"
   10225 		"\n"
   10226 		"// Sub routine uniform\n"
   10227 		"subroutine uniform routine_type routine;\n"
   10228 		"\n"
   10229 		"// Input data\n"
   10230 		"uniform vec4 uni_gs_left;\n"
   10231 		"uniform vec4 uni_gs_right;\n"
   10232 		"\n"
   10233 		"in vec4 tes_gs_result[];\n"
   10234 		"\n"
   10235 		"// Output\n"
   10236 		"out vec4 gs_fs_result;\n"
   10237 		"\n"
   10238 		"void main()\n"
   10239 		"{\n"
   10240 		"    gs_fs_result = routine(uni_gs_left, uni_gs_right) + tes_gs_result[0];\n"
   10241 		"}\n"
   10242 		"\n";
   10243 
   10244 	static const GLchar* fragmenty_shader_code =
   10245 		"#version 400 core\n"
   10246 		"#extension GL_ARB_shader_subroutine : require\n"
   10247 		"\n"
   10248 		"precision highp float;\n"
   10249 		"\n"
   10250 		"// Subroutine type\n"
   10251 		"subroutine vec4 routine_type(in vec4 left, in vec4 right);\n"
   10252 		"\n"
   10253 		"// Subroutine definition\n"
   10254 		"subroutine(routine_type) vec4 add(in vec4 left, in vec4 right)\n"
   10255 		"{\n"
   10256 		"    return left + right;\n"
   10257 		"}\n"
   10258 		"\n"
   10259 		"subroutine(routine_type) vec4 multiply(in vec4 left, in vec4 right)\n"
   10260 		"{\n"
   10261 		"    return left * right;\n"
   10262 		"}\n"
   10263 		"\n"
   10264 		"// Sub routine uniform\n"
   10265 		"subroutine uniform routine_type routine;\n"
   10266 		"\n"
   10267 		"// Input data\n"
   10268 		"uniform vec4 uni_fs_left;\n"
   10269 		"uniform vec4 uni_fs_right;\n"
   10270 		"\n"
   10271 		"in vec4 gs_fs_result;\n"
   10272 		"\n"
   10273 		"// Output\n"
   10274 		"out vec4 fs_out_result;\n"
   10275 		"\n"
   10276 		"void main()\n"
   10277 		"{\n"
   10278 		"    fs_out_result = routine(uni_fs_left, uni_fs_right) + gs_fs_result;\n"
   10279 		"}\n"
   10280 		"\n";
   10281 
   10282 	out_vertex_shader_code				   = vertex_shader_code;
   10283 	out_tesselation_control_shader_code	= tesselation_control_shader_code;
   10284 	out_tesselation_evaluation_shader_code = tesselation_evaluation_shader_code;
   10285 	out_geometry_shader_code			   = geometry_shader_code;
   10286 	out_fragment_shader_code			   = fragmenty_shader_code;
   10287 }
   10288 
   10289 /** Create <m_n_shared_contexts> shared contexts
   10290  *
   10291  **/
   10292 void FunctionalTest20_21::initSharedContexts()
   10293 {
   10294 	for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   10295 	{
   10296 		m_shared_contexts[i] = m_context.createSharedContext();
   10297 	}
   10298 }
   10299 
   10300 /** Prepare program(s)
   10301  *
   10302  * @param programs     An array of 5 programs' pointers. If monolithic program is prepared that only index m_fragment_stage_index should be initialized, otherwise all 5
   10303  * @param is_separable Select if monolithic or separable programs should be prepared
   10304  **/
   10305 void FunctionalTest20_21::prepareProgram(Utils::program** programs, bool is_separable)
   10306 {
   10307 	/* Get shader sources */
   10308 	const GLchar* vertex_shader_code;
   10309 	const GLchar* tesselation_control_shader_code;
   10310 	const GLchar* tesselation_evaluation_shader_code;
   10311 	const GLchar* geometry_shader_code;
   10312 	const GLchar* fragmenty_shader_code;
   10313 
   10314 	getShaders(vertex_shader_code, tesselation_control_shader_code, tesselation_evaluation_shader_code,
   10315 			   geometry_shader_code, fragmenty_shader_code);
   10316 
   10317 	/* Subroutines and uniform names */
   10318 	static const GLchar* subroutine_names[] = { "add", "multiply" };
   10319 	static const GLuint  n_subroutines		= sizeof(subroutine_names) / sizeof(subroutine_names[0]);
   10320 
   10321 	static const GLchar* subroutine_uniform_name = "routine";
   10322 
   10323 	/* Build program */
   10324 	if (false == is_separable)
   10325 	{
   10326 		programs[0]->build(0 /* compute shader source */, fragmenty_shader_code, geometry_shader_code,
   10327 						   tesselation_control_shader_code, tesselation_evaluation_shader_code, vertex_shader_code,
   10328 						   0 /* varying_names */, 0 /* n_varying_names */);
   10329 
   10330 		programs[m_geometry_stage_index]			   = programs[m_fragment_stage_index];
   10331 		programs[m_tesselation_control_stage_index]	= programs[m_fragment_stage_index];
   10332 		programs[m_tesselation_evaluation_stage_index] = programs[m_fragment_stage_index];
   10333 		programs[m_vertex_stage_index]				   = programs[m_fragment_stage_index];
   10334 	}
   10335 	else
   10336 	{
   10337 		programs[m_fragment_stage_index]->build(0, fragmenty_shader_code, 0, 0, 0, 0, 0, 0, true);
   10338 		programs[m_geometry_stage_index]->build(0, 0, geometry_shader_code, 0, 0, 0, 0, 0, true);
   10339 		programs[m_tesselation_control_stage_index]->build(0, 0, 0, tesselation_control_shader_code, 0, 0, 0, 0, true);
   10340 		programs[m_tesselation_evaluation_stage_index]->build(0, 0, 0, 0, tesselation_evaluation_shader_code, 0, 0, 0,
   10341 															  true);
   10342 		programs[m_vertex_stage_index]->build(0, 0, 0, 0, 0, vertex_shader_code, 0, 0, true);
   10343 	}
   10344 
   10345 	/* Get subroutine indices */
   10346 	for (GLuint i = 0; i < n_subroutines; ++i)
   10347 	{
   10348 		m_subroutine_indices[i].m_fragment_shader_stage =
   10349 			programs[m_fragment_stage_index]->getSubroutineIndex(subroutine_names[i], GL_FRAGMENT_SHADER);
   10350 
   10351 		m_subroutine_indices[i].m_geometry_shader_stage =
   10352 			programs[m_geometry_stage_index]->getSubroutineIndex(subroutine_names[i], GL_GEOMETRY_SHADER);
   10353 
   10354 		m_subroutine_indices[i].m_tesselation_control_shader_stage =
   10355 			programs[m_tesselation_control_stage_index]->getSubroutineIndex(subroutine_names[i],
   10356 																			GL_TESS_CONTROL_SHADER);
   10357 
   10358 		m_subroutine_indices[i].m_tesselation_evaluation_shader_stage =
   10359 			programs[m_tesselation_evaluation_stage_index]->getSubroutineIndex(subroutine_names[i],
   10360 																			   GL_TESS_EVALUATION_SHADER);
   10361 
   10362 		m_subroutine_indices[i].m_vertex_shader_stage =
   10363 			programs[m_vertex_stage_index]->getSubroutineIndex(subroutine_names[i], GL_VERTEX_SHADER);
   10364 	}
   10365 
   10366 	/* Get subroutine uniform locations */
   10367 	m_subroutine_uniform_locations.m_fragment_shader_stage =
   10368 		programs[m_fragment_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, GL_FRAGMENT_SHADER);
   10369 
   10370 	m_subroutine_uniform_locations.m_geometry_shader_stage =
   10371 		programs[m_geometry_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, GL_GEOMETRY_SHADER);
   10372 
   10373 	m_subroutine_uniform_locations.m_tesselation_control_shader_stage =
   10374 		programs[m_tesselation_control_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name,
   10375 																				  GL_TESS_CONTROL_SHADER);
   10376 
   10377 	m_subroutine_uniform_locations.m_tesselation_evaluation_shader_stage =
   10378 		programs[m_tesselation_evaluation_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name,
   10379 																					 GL_TESS_EVALUATION_SHADER);
   10380 
   10381 	m_subroutine_uniform_locations.m_vertex_shader_stage =
   10382 		programs[m_vertex_stage_index]->getSubroutineUniformLocation(subroutine_uniform_name, GL_VERTEX_SHADER);
   10383 }
   10384 
   10385 /** Generate program pipeline for current context and attach separable programs
   10386  *
   10387  * @param out_pipeline_id Id of generated pipeline
   10388  * @param programs        Collection of separable programs
   10389  **/
   10390 void FunctionalTest20_21::prepareProgramPipeline(glw::GLuint& out_pipeline_id, Utils::program** programs)
   10391 {
   10392 	/* GL entry points */
   10393 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10394 
   10395 	/* Generate */
   10396 	gl.genProgramPipelines(1, &out_pipeline_id);
   10397 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenProgramPipelines");
   10398 
   10399 	/* Bind */
   10400 	gl.bindProgramPipeline(out_pipeline_id);
   10401 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline");
   10402 
   10403 	/* Set up programs */
   10404 	gl.useProgramStages(out_pipeline_id, GL_FRAGMENT_SHADER_BIT, programs[m_fragment_stage_index]->m_program_object_id);
   10405 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
   10406 
   10407 	gl.useProgramStages(out_pipeline_id, GL_GEOMETRY_SHADER_BIT, programs[m_geometry_stage_index]->m_program_object_id);
   10408 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
   10409 
   10410 	gl.useProgramStages(out_pipeline_id, GL_TESS_CONTROL_SHADER_BIT,
   10411 						programs[m_tesselation_control_stage_index]->m_program_object_id);
   10412 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
   10413 
   10414 	gl.useProgramStages(out_pipeline_id, GL_TESS_EVALUATION_SHADER_BIT,
   10415 						programs[m_tesselation_evaluation_stage_index]->m_program_object_id);
   10416 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
   10417 
   10418 	gl.useProgramStages(out_pipeline_id, GL_VERTEX_SHADER_BIT, programs[m_vertex_stage_index]->m_program_object_id);
   10419 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages");
   10420 }
   10421 
   10422 /** Test specific case
   10423  *
   10424  * @param bit_field An array of 5 bit fields used to set up subroutine uniforms, one element per context
   10425  *
   10426  * @return True if test pass, false otherwise
   10427  **/
   10428 bool FunctionalTest20_21::testCase(const glw::GLuint bit_field[5])
   10429 {
   10430 	/* Storage for subroutine indices */
   10431 	subroutineUniformSet captured_subroutine_indices[m_n_shared_contexts + 1];
   10432 	subroutineUniformSet subroutine_indices[m_n_shared_contexts + 1];
   10433 
   10434 	/* Prepare subroutine_indices with bit fields */
   10435 	for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i)
   10436 	{
   10437 		subroutine_indices[i].set(bit_field[i], m_subroutine_indices);
   10438 	};
   10439 
   10440 	/* Update subroutine uniforms, each context gets different set */
   10441 	for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   10442 	{
   10443 		m_shared_contexts[i]->makeCurrent();
   10444 		updateCurrentSubroutineSet(subroutine_indices[i]);
   10445 	}
   10446 
   10447 	m_context.getRenderContext().makeCurrent();
   10448 	updateCurrentSubroutineSet(subroutine_indices[m_n_shared_contexts]);
   10449 
   10450 	/* Capture subroutine uniforms */
   10451 	for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   10452 	{
   10453 		m_shared_contexts[i]->makeCurrent();
   10454 		captureCurrentSubroutineSet(captured_subroutine_indices[i]);
   10455 	}
   10456 
   10457 	m_context.getRenderContext().makeCurrent();
   10458 	captureCurrentSubroutineSet(captured_subroutine_indices[m_n_shared_contexts]);
   10459 
   10460 	/* Verify that captured uniforms match expected values */
   10461 	for (GLuint i = 0; i < m_n_shared_contexts + 1; ++i)
   10462 	{
   10463 		if (subroutine_indices[i] != captured_subroutine_indices[i])
   10464 		{
   10465 			m_context.getTestContext().getLog()
   10466 				<< tcu::TestLog::Message << "Error."
   10467 				<< " Context: " << i << " VS, expected: " << subroutine_indices[i].m_vertex_shader_stage
   10468 				<< " captured: " << captured_subroutine_indices[i].m_vertex_shader_stage
   10469 				<< " TCS, expected: " << subroutine_indices[i].m_tesselation_control_shader_stage
   10470 				<< " captured: " << captured_subroutine_indices[i].m_tesselation_control_shader_stage
   10471 				<< " TES, expected: " << subroutine_indices[i].m_tesselation_evaluation_shader_stage
   10472 				<< " captured: " << captured_subroutine_indices[i].m_tesselation_evaluation_shader_stage
   10473 				<< " GS, expected: " << subroutine_indices[i].m_geometry_shader_stage
   10474 				<< " captured: " << captured_subroutine_indices[i].m_geometry_shader_stage
   10475 				<< " FS, expected: " << subroutine_indices[i].m_fragment_shader_stage
   10476 				<< " captured: " << captured_subroutine_indices[i].m_fragment_shader_stage << tcu::TestLog::EndMessage;
   10477 
   10478 			return false;
   10479 		}
   10480 	}
   10481 
   10482 	return true;
   10483 }
   10484 
   10485 /** Test a program or pipeline
   10486  *
   10487  * @param programs     An array of 5 programs\ pointers, as in preparePrograms
   10488  * @param is_separable Selects if monolithic or separable programs should be used
   10489  * @param test_cases   Collection of test cases
   10490  * @param n_test_cases Number of test cases
   10491  *
   10492  * @return True if all cases pass, false otherwise
   10493  **/
   10494 bool FunctionalTest20_21::testProgram(Utils::program** programs, bool is_separable, const glw::GLuint test_cases[][5],
   10495 									  glw::GLuint n_test_cases)
   10496 {
   10497 	/* Set program/pipeline as current for all contexts */
   10498 	if (false == is_separable)
   10499 	{
   10500 		programs[0]->use();
   10501 
   10502 		for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   10503 		{
   10504 			m_shared_contexts[i]->makeCurrent();
   10505 			programs[0]->use();
   10506 		}
   10507 	}
   10508 	else
   10509 	{
   10510 		/* GL entry points */
   10511 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10512 
   10513 		/* Make sure that program pipeline will be used */
   10514 		gl.useProgram(0);
   10515 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   10516 
   10517 		prepareProgramPipeline(m_program_pipelines[m_n_shared_contexts], programs);
   10518 
   10519 		for (GLuint i = 0; i < m_n_shared_contexts; ++i)
   10520 		{
   10521 			m_shared_contexts[i]->makeCurrent();
   10522 
   10523 			/* Make sure that program pipeline will be used */
   10524 			gl.useProgram(0);
   10525 			GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   10526 
   10527 			prepareProgramPipeline(m_program_pipelines[i], programs);
   10528 		}
   10529 	}
   10530 
   10531 	/* Execute test */
   10532 	bool result = true;
   10533 	for (GLuint i = 0; i < n_test_cases; ++i)
   10534 	{
   10535 		if (false == testCase(test_cases[i]))
   10536 		{
   10537 			result = false;
   10538 			break;
   10539 		}
   10540 	}
   10541 
   10542 	return result;
   10543 }
   10544 
   10545 /** Set up subroutine uniforms for current program or pipeline
   10546  *
   10547  * @param set Set of subroutine indices
   10548  **/
   10549 void FunctionalTest20_21::updateCurrentSubroutineSet(const subroutineUniformSet& set)
   10550 {
   10551 	/* GL entry points */
   10552 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10553 
   10554 	/* Fragment */
   10555 	gl.uniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1 /* count */, &set.m_fragment_shader_stage);
   10556 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   10557 
   10558 	/* Geometry */
   10559 	gl.uniformSubroutinesuiv(GL_GEOMETRY_SHADER, 1 /* count */, &set.m_geometry_shader_stage);
   10560 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   10561 
   10562 	/* Tess ctrl */
   10563 	gl.uniformSubroutinesuiv(GL_TESS_CONTROL_SHADER, 1 /* count */, &set.m_tesselation_control_shader_stage);
   10564 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   10565 
   10566 	/* Tess eval */
   10567 	gl.uniformSubroutinesuiv(GL_TESS_EVALUATION_SHADER, 1 /* count */, &set.m_tesselation_evaluation_shader_stage);
   10568 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   10569 
   10570 	/* Vertex */
   10571 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, 1 /* count */, &set.m_vertex_shader_stage);
   10572 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
   10573 }
   10574 
   10575 /** Constructor.
   10576  *
   10577  *  @param context Rendering context.
   10578  *
   10579  **/
   10580 NegativeTest1::NegativeTest1(deqp::Context& context)
   10581 	: TestCase(context, "subroutine_errors", "Verifies all GL_INVALID_OPERATION, GL_INVALID_VALUE, GL_INVALID ENUM "
   10582 											 "errors related to subroutine usage are properly generated.")
   10583 	, m_has_test_passed(true)
   10584 	, m_po_active_subroutine_uniform_locations(0)
   10585 	, m_po_active_subroutine_uniforms(0)
   10586 	, m_po_active_subroutines(0)
   10587 	, m_po_subroutine_uniform_function_index(-1)
   10588 	, m_po_subroutine_uniform_function2_index(-1)
   10589 	, m_po_subroutine_test1_index(GL_INVALID_INDEX)
   10590 	, m_po_subroutine_test2_index(GL_INVALID_INDEX)
   10591 	, m_po_subroutine_test3_index(GL_INVALID_INDEX)
   10592 	, m_po_not_linked_id(0)
   10593 	, m_po_id(0)
   10594 	, m_vs_id(0)
   10595 {
   10596 	/* Left blank intentionally */
   10597 }
   10598 
   10599 /** Deinitializes all GL objects that may have been created during
   10600  *  test execution.
   10601  **/
   10602 void NegativeTest1::deinit()
   10603 {
   10604 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   10605 
   10606 	if (m_po_id != 0)
   10607 	{
   10608 		gl.deleteProgram(m_po_id);
   10609 
   10610 		m_po_id = 0;
   10611 	}
   10612 
   10613 	if (m_po_not_linked_id != 0)
   10614 	{
   10615 		gl.deleteProgram(m_po_not_linked_id);
   10616 
   10617 		m_po_not_linked_id = 0;
   10618 	}
   10619 
   10620 	if (m_vs_id != 0)
   10621 	{
   10622 		gl.deleteShader(m_vs_id);
   10623 
   10624 		m_vs_id = 0;
   10625 	}
   10626 }
   10627 
   10628 /** Initializes all GL objects required to run the test.  */
   10629 void NegativeTest1::initTest()
   10630 {
   10631 	glw::GLint			  compile_status = GL_FALSE;
   10632 	const glw::Functions& gl			 = m_context.getRenderContext().getFunctions();
   10633 
   10634 	/* Create program objects */
   10635 	m_po_not_linked_id = gl.createProgram();
   10636 	m_po_id			   = gl.createProgram();
   10637 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
   10638 
   10639 	/* Create vertex shader object */
   10640 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   10641 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   10642 
   10643 	/* Set up vertex shader */
   10644 	const char* vs_body = "#version 400\n"
   10645 						  "\n"
   10646 						  "#extension GL_ARB_shader_subroutine : require\n"
   10647 						  "\n"
   10648 						  "subroutine void subroutineType (out ivec2 arg);\n"
   10649 						  "subroutine void subroutineType2(out ivec4 arg);\n"
   10650 						  "\n"
   10651 						  "subroutine(subroutineType) void test1(out ivec2 arg)\n"
   10652 						  "{\n"
   10653 						  "    arg = ivec2(1, 2);\n"
   10654 						  "}\n"
   10655 						  "subroutine(subroutineType) void test2(out ivec2 arg)\n"
   10656 						  "{\n"
   10657 						  "    arg = ivec2(3,4);\n"
   10658 						  "}\n"
   10659 						  "subroutine(subroutineType2) void test3(out ivec4 arg)\n"
   10660 						  "{\n"
   10661 						  "    arg = ivec4(1, 2, 3, 4);\n"
   10662 						  "}\n"
   10663 						  "\n"
   10664 						  "subroutine uniform subroutineType  function;\n"
   10665 						  "subroutine uniform subroutineType2 function2;\n"
   10666 						  "\n"
   10667 						  "void main()\n"
   10668 						  "{\n"
   10669 						  "    ivec2 test;\n"
   10670 						  "    ivec4 test2;\n"
   10671 						  "\n"
   10672 						  "    function(test);\n"
   10673 						  "\n"
   10674 						  "    if (test.x > 2)\n"
   10675 						  "    {\n"
   10676 						  "        gl_Position = vec4(1);\n"
   10677 						  "    }\n"
   10678 						  "    else\n"
   10679 						  "    {\n"
   10680 						  "        function2(test2);\n"
   10681 						  "\n"
   10682 						  "        gl_Position = vec4(float(test2.x) );\n"
   10683 						  "    }\n"
   10684 						  "}\n";
   10685 
   10686 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
   10687 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
   10688 
   10689 	gl.compileShader(m_vs_id);
   10690 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
   10691 
   10692 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   10693 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
   10694 
   10695 	if (compile_status == GL_FALSE)
   10696 	{
   10697 		TCU_FAIL("Shader compilation failed");
   10698 	}
   10699 
   10700 	/* Set up & link the test program object */
   10701 	glw::GLint link_status = GL_FALSE;
   10702 
   10703 	gl.attachShader(m_po_id, m_vs_id);
   10704 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   10705 
   10706 	gl.linkProgram(m_po_id);
   10707 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   10708 
   10709 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   10710 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   10711 
   10712 	if (link_status == GL_FALSE)
   10713 	{
   10714 		TCU_FAIL("Program linking failed");
   10715 	}
   10716 
   10717 	/* Query test program object's properties */
   10718 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS,
   10719 						 &m_po_active_subroutine_uniform_locations);
   10720 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &m_po_active_subroutine_uniforms);
   10721 	gl.getProgramStageiv(m_po_id, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &m_po_active_subroutines);
   10722 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramStageiv() call(s) failed.");
   10723 
   10724 	if (m_po_active_subroutine_uniform_locations != 2)
   10725 	{
   10726 		TCU_FAIL("Invalid GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS value returned");
   10727 	}
   10728 
   10729 	m_po_subroutine_test1_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test1");
   10730 	m_po_subroutine_test2_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test2");
   10731 	m_po_subroutine_test3_index = gl.getSubroutineIndex(m_po_id, GL_VERTEX_SHADER, "test3");
   10732 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() call(s) failed.");
   10733 
   10734 	if (m_po_subroutine_test1_index == GL_INVALID_INDEX || m_po_subroutine_test2_index == GL_INVALID_INDEX ||
   10735 		m_po_subroutine_test3_index == GL_INVALID_INDEX)
   10736 	{
   10737 		TCU_FAIL("Invalid subroutine index returned");
   10738 	}
   10739 
   10740 	m_po_subroutine_uniform_function_index  = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "function");
   10741 	m_po_subroutine_uniform_function2_index = gl.getSubroutineUniformLocation(m_po_id, GL_VERTEX_SHADER, "function2");
   10742 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() call(s) failed.");
   10743 
   10744 	if (m_po_subroutine_uniform_function_index == -1 || m_po_subroutine_uniform_function2_index == -1)
   10745 	{
   10746 		TCU_FAIL("Invalid subroutine uniform index returned");
   10747 	}
   10748 }
   10749 
   10750 /** Executes test iteration.
   10751  *
   10752  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   10753  */
   10754 tcu::TestNode::IterateResult NegativeTest1::iterate()
   10755 {
   10756 	glw::GLenum			  error_code = GL_NO_ERROR;
   10757 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
   10758 
   10759 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   10760 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   10761 	{
   10762 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   10763 	}
   10764 
   10765 	/* Initialize GL objects required to run the test */
   10766 	initTest();
   10767 
   10768 	/* The error INVALID_OPERATION is generated by GetSubroutineUniformLocation
   10769 	 * if the program object identified by <program> has not been successfully
   10770 	 * linked.
   10771 	 */
   10772 	gl.getSubroutineUniformLocation(m_po_not_linked_id, GL_FRAGMENT_SHADER, "subroutine_uniform_name");
   10773 
   10774 	error_code = gl.getError();
   10775 
   10776 	if (error_code != GL_INVALID_OPERATION)
   10777 	{
   10778 		m_testCtx.getLog() << tcu::TestLog::Message
   10779 						   << "glGetSubroutineUniformLocation() does not generate GL_INVALID_OPERATION "
   10780 							  "error code when called for a non-linked program object."
   10781 						   << tcu::TestLog::EndMessage;
   10782 
   10783 		m_has_test_passed = false;
   10784 	}
   10785 
   10786 	/* The error INVALID_VALUE is generated by GetActiveSubroutineUniformiv or
   10787 	 * GetActiveSubroutineUniformName if <index> is greater than or equal to the
   10788 	 * value of ACTIVE_SUBROUTINE_UNIFORMS for the shader stage.
   10789 	 */
   10790 	glw::GLint temp_length = 0;
   10791 	glw::GLint temp_values = 0;
   10792 
   10793 	gl.getActiveSubroutineUniformiv(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms,
   10794 									GL_NUM_COMPATIBLE_SUBROUTINES, &temp_values);
   10795 	error_code = gl.getError();
   10796 
   10797 	if (error_code == GL_INVALID_VALUE)
   10798 	{
   10799 		gl.getActiveSubroutineUniformiv(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms + 1,
   10800 										GL_NUM_COMPATIBLE_SUBROUTINES, &temp_values);
   10801 
   10802 		error_code = gl.getError();
   10803 	}
   10804 
   10805 	if (error_code != GL_INVALID_VALUE)
   10806 	{
   10807 		m_testCtx.getLog() << tcu::TestLog::Message
   10808 						   << "glGetActiveSubroutineUniformiv() does not generate GL_INVALID_VALUE "
   10809 							  "when passed <index> argument that is greater than or equal to "
   10810 							  "the value of GL_ACTIVE_SUBROUTINE_UNIFORMS."
   10811 						   << tcu::TestLog::EndMessage;
   10812 
   10813 		m_has_test_passed = false;
   10814 	}
   10815 
   10816 	gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms, 0, /* bufsize */
   10817 									  &temp_length, DE_NULL);										 /* name */
   10818 	error_code = gl.getError();
   10819 
   10820 	if (error_code == GL_INVALID_VALUE)
   10821 	{
   10822 		gl.getActiveSubroutineUniformName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutine_uniforms + 1,
   10823 										  0,					  /* bufsize */
   10824 										  &temp_length, DE_NULL); /* name */
   10825 
   10826 		error_code = gl.getError();
   10827 	}
   10828 
   10829 	if (error_code != GL_INVALID_VALUE)
   10830 	{
   10831 		m_testCtx.getLog() << tcu::TestLog::Message
   10832 						   << "glGetActiveSubroutineUniformName() does not generate GL_INVALID_VALUE "
   10833 							  "when passed <index> argument that is greater than or equal to "
   10834 							  "the value of GL_ACTIVE_SUBROUTINE_UNIFORMS."
   10835 						   << tcu::TestLog::EndMessage;
   10836 
   10837 		m_has_test_passed = false;
   10838 	}
   10839 
   10840 	/* The error INVALID_VALUE is generated by GetActiveSubroutineName if <index>
   10841 	 * is greater than or equal to the value of ACTIVE_SUBROUTINES for the shader
   10842 	 * stage.
   10843 	 */
   10844 	gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutines, 0, /* bufsize */
   10845 							   &temp_length, DE_NULL);								  /* name */
   10846 	error_code = gl.getError();
   10847 
   10848 	if (error_code == GL_INVALID_VALUE)
   10849 	{
   10850 		gl.getActiveSubroutineName(m_po_id, GL_VERTEX_SHADER, m_po_active_subroutines + 1, 0, /* bufsize */
   10851 								   &temp_length, DE_NULL);									  /* name */
   10852 
   10853 		error_code = gl.getError();
   10854 	}
   10855 
   10856 	if (error_code != GL_INVALID_VALUE)
   10857 	{
   10858 		m_testCtx.getLog() << tcu::TestLog::Message << "glGetActiveSubroutineName() does not generate GL_INVALID_VALUE "
   10859 													   "when passed <index> argument that is greater than or equal to "
   10860 													   "the value of GL_ACTIVE_SUBROUTINES."
   10861 						   << tcu::TestLog::EndMessage;
   10862 
   10863 		m_has_test_passed = false;
   10864 	}
   10865 
   10866 	/* The error INVALID_VALUE is generated by UniformSubroutinesuiv if <count>
   10867 	 * is not equal to the value of ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the
   10868 	 * shader stage <shadertype>.
   10869 	 */
   10870 	glw::GLuint index = 0;
   10871 
   10872 	gl.useProgram(m_po_id);
   10873 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10874 
   10875 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations - 1, &index);
   10876 	error_code = gl.getError();
   10877 
   10878 	if (error_code == GL_INVALID_VALUE)
   10879 	{
   10880 		gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations + 1, &index);
   10881 
   10882 		error_code = gl.getError();
   10883 	}
   10884 
   10885 	if (error_code != GL_INVALID_VALUE)
   10886 	{
   10887 		m_testCtx.getLog() << tcu::TestLog::Message << "glUniformSubroutinesiv() does not generate GL_INVALID_VALUE "
   10888 													   "when passed <count> argument that is not equal to the value of "
   10889 													   "GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS."
   10890 						   << tcu::TestLog::EndMessage;
   10891 
   10892 		m_has_test_passed = false;
   10893 	}
   10894 
   10895 	/* The error INVALID_VALUE is generated by UniformSubroutinesuiv if any value
   10896 	 * in <indices> is greater than or equal to the value of ACTIVE_SUBROUTINES
   10897 	 * for the shader stage.
   10898 	 */
   10899 	glw::GLuint invalid_subroutine_indices[4] = { (GLuint)m_po_active_subroutines, (GLuint)m_po_active_subroutines,
   10900 												  (GLuint)m_po_active_subroutines + 1,
   10901 												  (GLuint)m_po_active_subroutines + 1 };
   10902 
   10903 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, /* count */
   10904 							 invalid_subroutine_indices + 0);
   10905 	error_code = gl.getError();
   10906 
   10907 	if (error_code == GL_INVALID_VALUE)
   10908 	{
   10909 		gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations,
   10910 								 invalid_subroutine_indices + 2);
   10911 
   10912 		error_code = gl.getError();
   10913 	}
   10914 
   10915 	if (error_code != GL_INVALID_VALUE)
   10916 	{
   10917 		m_testCtx.getLog() << tcu::TestLog::Message << "glUniformSubroutinesuiv() does not generate GL_INVALID_VALUE "
   10918 													   "when the value passed via <indices> argument is greater than "
   10919 													   "or equal to the value of GL_ACTIVE_SUBROUTINES."
   10920 						   << tcu::TestLog::EndMessage;
   10921 
   10922 		m_has_test_passed = false;
   10923 	}
   10924 
   10925 	/* The error INVALID_OPERATION is generated by UniformSubroutinesuiv() if any
   10926 	 * subroutine index in <indices> identifies a subroutine not associated with
   10927 	 * the type of the subroutine uniform variable assigned to the corresponding
   10928 	 * location.
   10929 	 */
   10930 	glw::GLuint invalid_subroutine_indices2[2] = { m_po_subroutine_test1_index, m_po_subroutine_test1_index };
   10931 
   10932 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, invalid_subroutine_indices2);
   10933 	error_code = gl.getError();
   10934 
   10935 	if (error_code != GL_INVALID_OPERATION)
   10936 	{
   10937 		m_testCtx.getLog() << tcu::TestLog::Message
   10938 						   << "glUniformSubroutinesuiv() does not generate GL_INVALID_OPERATION "
   10939 							  "when the subroutine index passed via <indices> argument identifies"
   10940 							  "a subroutine not associated with the type of the subroutine uniform "
   10941 							  "assigned to the corresponding location."
   10942 						   << tcu::TestLog::EndMessage;
   10943 
   10944 		m_has_test_passed = false;
   10945 	}
   10946 
   10947 	/* The error INVALID_OPERATION is generated by UniformSubroutinesuiv if no
   10948 	 * program is active.
   10949 	 */
   10950 	glw::GLuint valid_subroutine_locations[2] = { 0 };
   10951 
   10952 	valid_subroutine_locations[m_po_subroutine_uniform_function_index]  = m_po_subroutine_test1_index;
   10953 	valid_subroutine_locations[m_po_subroutine_uniform_function2_index] = m_po_subroutine_test3_index;
   10954 
   10955 	gl.useProgram(0);
   10956 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10957 
   10958 	gl.uniformSubroutinesuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, valid_subroutine_locations);
   10959 	error_code = gl.getError();
   10960 
   10961 	if (error_code != GL_INVALID_OPERATION)
   10962 	{
   10963 		m_testCtx.getLog() << tcu::TestLog::Message
   10964 						   << "glUniformSubroutinesuiv() does not generate GL_INVALID_OPERATION "
   10965 							  "when called without an active program object."
   10966 						   << tcu::TestLog::EndMessage;
   10967 
   10968 		m_has_test_passed = false;
   10969 	}
   10970 
   10971 	/* The error INVALID_VALUE is generated by GetUniformSubroutineuiv if
   10972 	 * <location> is greater than or equal to the value of
   10973 	 * ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the shader stage.
   10974 	 */
   10975 	glw::GLuint temp_value = 0;
   10976 
   10977 	gl.useProgram(m_po_id);
   10978 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   10979 
   10980 	gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations, &temp_value);
   10981 	error_code = gl.getError();
   10982 
   10983 	if (error_code == GL_INVALID_VALUE)
   10984 	{
   10985 		gl.getUniformSubroutineuiv(GL_VERTEX_SHADER, m_po_active_subroutine_uniform_locations + 1, &temp_value);
   10986 		error_code = gl.getError();
   10987 	}
   10988 
   10989 	if (error_code != GL_INVALID_VALUE)
   10990 	{
   10991 		m_testCtx.getLog() << tcu::TestLog::Message
   10992 						   << "glGetUniformSubroutineuiv() does not generate GL_INVALID_VALUE "
   10993 							  "when called for location that is greater than or equal to the value "
   10994 							  "of GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS."
   10995 						   << tcu::TestLog::EndMessage;
   10996 
   10997 		m_has_test_passed = false;
   10998 	}
   10999 
   11000 	/* The error INVALID_OPERATION is generated by GetUniformSubroutineuiv if no
   11001 	 * program is active for the shader stage identified by <shadertype>.
   11002 	 */
   11003 	const glw::GLenum undefined_shader_stages[] = { GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_TESS_CONTROL_SHADER,
   11004 													GL_TESS_EVALUATION_SHADER };
   11005 	const unsigned int n_undefined_shader_stages = sizeof(undefined_shader_stages) / sizeof(undefined_shader_stages[0]);
   11006 
   11007 	for (unsigned int n_undefined_shader_stage = 0; n_undefined_shader_stage < n_undefined_shader_stages;
   11008 		 ++n_undefined_shader_stage)
   11009 	{
   11010 		glw::GLenum shader_stage = undefined_shader_stages[n_undefined_shader_stage];
   11011 
   11012 		gl.getUniformSubroutineuiv(shader_stage, 0, /* location */
   11013 								   &temp_value);
   11014 		error_code = gl.getError();
   11015 
   11016 		if (error_code != GL_INVALID_OPERATION)
   11017 		{
   11018 			m_testCtx.getLog() << tcu::TestLog::Message
   11019 							   << "glGetUniformSubroutineuiv() does not generate GL_INVALID_OPERATION "
   11020 								  "when called for a shader stage that is not defined for active "
   11021 								  "program object."
   11022 							   << tcu::TestLog::EndMessage;
   11023 
   11024 			m_has_test_passed = false;
   11025 		}
   11026 	} /* for (all undefined shader stages) */
   11027 
   11028 	/* All done */
   11029 	if (m_has_test_passed)
   11030 	{
   11031 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   11032 	}
   11033 	else
   11034 	{
   11035 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   11036 	}
   11037 
   11038 	return STOP;
   11039 }
   11040 
   11041 /** Constructor
   11042  *
   11043  *  @param context Rendering context.
   11044  *
   11045  **/
   11046 NegativeTest2::NegativeTest2(deqp::Context& context)
   11047 	: TestCase(context, "subroutine_uniform_scope", "Verifies subroutine uniforms declared in shader stage A"
   11048 													"cannot be accessed from a different stage.")
   11049 	, m_fs_id(0)
   11050 	, m_gs_id(0)
   11051 	, m_has_test_passed(true)
   11052 	, m_po_id(0)
   11053 	, m_tc_id(0)
   11054 	, m_te_id(0)
   11055 	, m_vs_id(0)
   11056 {
   11057 	/* Left blank intentionally */
   11058 }
   11059 
   11060 /** Deinitializes all GL objects that may have been created during test execution */
   11061 void NegativeTest2::deinit()
   11062 {
   11063 	deinitGLObjects();
   11064 }
   11065 
   11066 /** Deinitializes all GL objects that may have been created during test execution */
   11067 void NegativeTest2::deinitGLObjects()
   11068 {
   11069 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11070 
   11071 	if (m_fs_id != 0)
   11072 	{
   11073 		gl.deleteShader(m_fs_id);
   11074 
   11075 		m_fs_id = 0;
   11076 	}
   11077 
   11078 	if (m_gs_id != 0)
   11079 	{
   11080 		gl.deleteShader(m_gs_id);
   11081 
   11082 		m_gs_id = 0;
   11083 	}
   11084 
   11085 	if (m_tc_id != 0)
   11086 	{
   11087 		gl.deleteShader(m_tc_id);
   11088 
   11089 		m_tc_id = 0;
   11090 	}
   11091 
   11092 	if (m_te_id != 0)
   11093 	{
   11094 		gl.deleteShader(m_te_id);
   11095 
   11096 		m_te_id = 0;
   11097 	}
   11098 
   11099 	if (m_vs_id != 0)
   11100 	{
   11101 		gl.deleteShader(m_vs_id);
   11102 
   11103 		m_vs_id = 0;
   11104 	}
   11105 
   11106 	if (m_po_id != 0)
   11107 	{
   11108 		gl.deleteProgram(m_po_id);
   11109 
   11110 		m_po_id = 0;
   11111 	}
   11112 }
   11113 
   11114 /** Builds an offending program object and tries to link it. We're either expecting
   11115  *  a compile-time or link-time error here.
   11116  *
   11117  *  If the program object builds successfully, the test has failed.
   11118  *
   11119  *  @param referencing_stage Shader stage which defines a subroutine uniform that
   11120  *                           should be called from fragment/geometry/tess control/
   11121  *                           tess evaluation/vertex shader stages.
   11122  *
   11123  **/
   11124 void NegativeTest2::executeTestCase(const Utils::_shader_stage& referencing_stage)
   11125 {
   11126 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11127 
   11128 	const std::string fs_body = getFragmentShaderBody(referencing_stage);
   11129 	const std::string gs_body = getGeometryShaderBody(referencing_stage);
   11130 	const std::string tc_body = getTessellationControlShaderBody(referencing_stage);
   11131 	const std::string te_body = getTessellationEvaluationShaderBody(referencing_stage);
   11132 	const std::string vs_body = getVertexShaderBody(referencing_stage);
   11133 
   11134 	if (Utils::buildProgram(gl, vs_body, tc_body, te_body, gs_body, fs_body, NULL, /* xfb_varyings */
   11135 							0,													   /* n_xfb_varyings */
   11136 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   11137 	{
   11138 		/* Test program should not have built correctly ! */
   11139 		m_testCtx.getLog() << tcu::TestLog::Message << "In the following program, one of the stages references "
   11140 													   "a subroutine that is defined in another stage. This "
   11141 													   "is forbidden by the specification.\n"
   11142 													   "\n"
   11143 													   "Vertex shader:\n\n"
   11144 						   << vs_body.c_str() << "\n\nTessellation control shader:\n\n"
   11145 						   << tc_body.c_str() << "\n\nTessellation evaluation shader:\n\n"
   11146 						   << te_body.c_str() << "\n\nGeometry shader:\n\n"
   11147 						   << gs_body.c_str() << "\n\nFragment shader:\n\n"
   11148 						   << fs_body.c_str() << tcu::TestLog::EndMessage;
   11149 
   11150 		m_has_test_passed = false;
   11151 	} /* if (test program was built successfully) */
   11152 
   11153 	/* Release the shaders & the program object that buildProgram() created */
   11154 	deinitGLObjects();
   11155 }
   11156 
   11157 /** Retrieves an offending fragment shader body.
   11158  *
   11159  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   11160  *                           will be called from fragment shader.
   11161  *
   11162  *  @return Requested string.
   11163  **/
   11164 std::string NegativeTest2::getFragmentShaderBody(const Utils::_shader_stage& referencing_stage) const
   11165 {
   11166 	std::stringstream result;
   11167 
   11168 	/* Form the pre-amble */
   11169 	result << "#version 400\n"
   11170 			  "\n"
   11171 			  "#extension GL_ARB_shader_subroutine : require\n"
   11172 			  "\n"
   11173 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   11174 			  "\n"
   11175 			  /* Define a subroutine */
   11176 			  "subroutine(testSubroutineType) void fs_subroutine(out vec4 test_argument)\n"
   11177 			  "{\n"
   11178 			  "    test_argument = vec4(1, 0, 0, 0);\n"
   11179 			  "}\n"
   11180 			  "\n"
   11181 			  /* Define output variables */
   11182 			  "out vec4 result;\n"
   11183 			  "\n"
   11184 			  /* Define uniforms */
   11185 			  "subroutine uniform testSubroutineType test_fs_subroutine;\n"
   11186 			  "\n"
   11187 			  /* Define main() */
   11188 			  "void main()\n"
   11189 			  "{\n"
   11190 			  "    "
   11191 		   << getSubroutineUniformName(referencing_stage) << "(result);\n"
   11192 															 "}\n";
   11193 
   11194 	return result.str();
   11195 }
   11196 
   11197 /** Retrieves an offending geometry shader body.
   11198  *
   11199  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   11200  *                           will be called from geometry shader.
   11201  *
   11202  *  @return Requested string.
   11203  **/
   11204 std::string NegativeTest2::getGeometryShaderBody(const Utils::_shader_stage& referencing_stage) const
   11205 {
   11206 	std::stringstream result;
   11207 
   11208 	/* Form the pre-amble */
   11209 	result << "#version 400\n"
   11210 			  "\n"
   11211 			  "#extension GL_ARB_shader_subroutine : require\n"
   11212 			  "\n"
   11213 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   11214 			  "\n"
   11215 			  "layout(points)                   in;\n"
   11216 			  "layout(points, max_vertices = 1) out;\n"
   11217 			  "\n"
   11218 			  /* Define a subroutine */
   11219 			  "subroutine(testSubroutineType) void gs_subroutine(out vec4 test_argument)\n"
   11220 			  "{\n"
   11221 			  "    test_argument = vec4(0, 1, 1, 1);\n"
   11222 			  "}\n"
   11223 			  "\n"
   11224 			  /* Define output variables */
   11225 			  "out vec4 result;\n"
   11226 			  "\n"
   11227 			  /* Define uniforms */
   11228 			  "subroutine uniform testSubroutineType test_gs_subroutine;\n"
   11229 			  "\n"
   11230 			  /* Define main() */
   11231 			  "void main()\n"
   11232 			  "{\n"
   11233 			  "    "
   11234 		   << getSubroutineUniformName(referencing_stage) << "(result);\n"
   11235 															 "}\n";
   11236 
   11237 	return result.str();
   11238 }
   11239 
   11240 /** Retrieves name of the subroutine uniform that is defined in user-specified
   11241  *  shader stage.
   11242  *
   11243  *  @param stage Shader stage to retrieve the subroutine uniform name for.
   11244  *
   11245  *  @return As per description.
   11246  **/
   11247 std::string NegativeTest2::getSubroutineUniformName(const Utils::_shader_stage& stage) const
   11248 {
   11249 	std::string result = "?";
   11250 
   11251 	switch (stage)
   11252 	{
   11253 	case Utils::SHADER_STAGE_FRAGMENT:
   11254 	{
   11255 		result = "test_fs_subroutine";
   11256 
   11257 		break;
   11258 	}
   11259 
   11260 	case Utils::SHADER_STAGE_GEOMETRY:
   11261 	{
   11262 		result = "test_gs_subroutine";
   11263 
   11264 		break;
   11265 	}
   11266 
   11267 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   11268 	{
   11269 		result = "test_tc_subroutine";
   11270 
   11271 		break;
   11272 	}
   11273 
   11274 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   11275 	{
   11276 		result = "test_te_subroutine";
   11277 
   11278 		break;
   11279 	}
   11280 
   11281 	case Utils::SHADER_STAGE_VERTEX:
   11282 	{
   11283 		result = "test_vs_subroutine";
   11284 
   11285 		break;
   11286 	}
   11287 
   11288 	default:
   11289 	{
   11290 		TCU_FAIL("Unrecognized shader stage requested");
   11291 	}
   11292 	} /* switch (stage) */
   11293 
   11294 	return result;
   11295 }
   11296 
   11297 /** Retrieves an offending tessellation control shader body.
   11298  *
   11299  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   11300  *                           will be called from tessellation control shader.
   11301  *
   11302  *  @return Requested string.
   11303  **/
   11304 std::string NegativeTest2::getTessellationControlShaderBody(const Utils::_shader_stage& referencing_stage) const
   11305 {
   11306 	std::stringstream result;
   11307 
   11308 	/* Form the pre-amble */
   11309 	result << "#version 400\n"
   11310 			  "\n"
   11311 			  "#extension GL_ARB_shader_subroutine : require\n"
   11312 			  "\n"
   11313 			  "layout(vertices = 4) out;\n"
   11314 			  "\n"
   11315 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   11316 			  "\n"
   11317 			  /* Define a subroutine */
   11318 			  "subroutine(testSubroutineType) void tc_subroutine(out vec4 test_argument)\n"
   11319 			  "{\n"
   11320 			  "    test_argument = vec4(0, 0, 1, 0);\n"
   11321 			  "}\n"
   11322 			  "\n"
   11323 			  /* Define uniforms */
   11324 			  "subroutine uniform testSubroutineType test_tc_subroutine;\n"
   11325 			  "\n"
   11326 			  /* Define main() */
   11327 			  "void main()\n"
   11328 			  "{\n"
   11329 			  "    "
   11330 		   << getSubroutineUniformName(referencing_stage) << "(gl_out[gl_InvocationID].gl_Position);\n"
   11331 															 "}\n";
   11332 
   11333 	return result.str();
   11334 }
   11335 
   11336 /** Retrieves an offending tessellation evaluation shader body.
   11337  *
   11338  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   11339  *                           will be called from tessellation evaluation shader.
   11340  *
   11341  *  @return Requested string.
   11342  **/
   11343 std::string NegativeTest2::getTessellationEvaluationShaderBody(const Utils::_shader_stage& referencing_stage) const
   11344 {
   11345 	std::stringstream result;
   11346 
   11347 	/* Form the pre-amble */
   11348 	result << "#version 400\n"
   11349 			  "\n"
   11350 			  "#extension GL_ARB_shader_subroutine : require\n"
   11351 			  "\n"
   11352 			  "layout(quads) in;\n"
   11353 			  "\n"
   11354 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   11355 			  "\n"
   11356 			  /* Define a subroutine */
   11357 			  "subroutine(testSubroutineType) void te_subroutine(out vec4 test_argument)\n"
   11358 			  "{\n"
   11359 			  "    test_argument = vec4(1, 1, 1, 1);\n"
   11360 			  "}\n"
   11361 			  "\n"
   11362 			  /* Define uniforms */
   11363 			  "subroutine uniform testSubroutineType test_te_subroutine;\n"
   11364 			  "\n"
   11365 			  /* Define main() */
   11366 			  "void main()\n"
   11367 			  "{\n"
   11368 			  "    "
   11369 		   << getSubroutineUniformName(referencing_stage) << "(gl_Position);\n"
   11370 															 "}\n";
   11371 
   11372 	return result.str();
   11373 }
   11374 
   11375 /** Retrieves an offending vertex shader body.
   11376  *
   11377  *  @param referencing_stage Shader stage which defines the subroutine uniform that
   11378  *                           will be called from vertex shader.
   11379  *
   11380  *  @return Requested string.
   11381  **/
   11382 std::string NegativeTest2::getVertexShaderBody(const Utils::_shader_stage& referencing_stage) const
   11383 {
   11384 	std::stringstream result;
   11385 
   11386 	/* Form the pre-amble */
   11387 	result << "#version 400\n"
   11388 			  "\n"
   11389 			  "#extension GL_ARB_shader_subroutine : require\n"
   11390 			  "\n"
   11391 			  "subroutine void testSubroutineType(out vec4 test_argument);\n"
   11392 			  "\n"
   11393 			  /* Define a subroutine */
   11394 			  "subroutine(testSubroutineType) void vs_subroutine(out vec4 test_argument)\n"
   11395 			  "{\n"
   11396 			  "    test_argument = vec4(0, 1, 0, 0);\n"
   11397 			  "}\n"
   11398 			  "\n"
   11399 			  /* Define uniforms */
   11400 			  "subroutine uniform testSubroutineType test_vs_subroutine;\n"
   11401 			  "\n"
   11402 			  /* Define main() */
   11403 			  "void main()\n"
   11404 			  "{\n"
   11405 			  "    "
   11406 		   << getSubroutineUniformName(referencing_stage) << "(gl_Position);\n"
   11407 															 "}\n";
   11408 
   11409 	return result.str();
   11410 }
   11411 
   11412 /** Executes test iteration.
   11413  *
   11414  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   11415  */
   11416 tcu::TestNode::IterateResult NegativeTest2::iterate()
   11417 {
   11418 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   11419 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   11420 	{
   11421 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   11422 	}
   11423 
   11424 	/* Iterate over all shader stages and execute the checks */
   11425 	for (int referencing_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   11426 		 referencing_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++referencing_stage)
   11427 	{
   11428 		executeTestCase(static_cast<Utils::_shader_stage>(referencing_stage));
   11429 	} /* for (all test cases) */
   11430 
   11431 	/* All done */
   11432 	if (m_has_test_passed)
   11433 	{
   11434 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   11435 	}
   11436 	else
   11437 	{
   11438 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   11439 	}
   11440 
   11441 	return STOP;
   11442 }
   11443 
   11444 /** Constructor.
   11445  *
   11446  *  @param context Rendering context.
   11447  *
   11448  **/
   11449 NegativeTest3::NegativeTest3(deqp::Context& context)
   11450 	: TestCase(context, "missing_subroutine_keyword", "Verifies that subroutine keyword is necessary when declaring a "
   11451 													  "subroutine uniforn and a compilation error occurs without it.")
   11452 	, m_has_test_passed(true)
   11453 	, m_so_id(0)
   11454 {
   11455 	/* Left blank intentionally */
   11456 }
   11457 
   11458 /** Deinitializes all GL objects that may have been created during test execution */
   11459 void NegativeTest3::deinit()
   11460 {
   11461 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11462 
   11463 	if (m_so_id != 0)
   11464 	{
   11465 		gl.deleteShader(m_so_id);
   11466 
   11467 		m_so_id = 0;
   11468 	}
   11469 }
   11470 
   11471 /** Verifies that broken shader (for user-specified shader stage) does not compile.
   11472  *
   11473  *  @param shader_stage Shader stage to use for the test.
   11474  **/
   11475 void NegativeTest3::executeTest(const Utils::_shader_stage& shader_stage)
   11476 {
   11477 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11478 
   11479 	/* Generate a new shader object */
   11480 	m_so_id = gl.createShader(Utils::getGLenumForShaderStage(shader_stage));
   11481 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   11482 
   11483 	/* Assign body to the shader */
   11484 	std::string body;
   11485 	const char* body_raw_ptr = DE_NULL;
   11486 
   11487 	switch (shader_stage)
   11488 	{
   11489 	case Utils::SHADER_STAGE_VERTEX:
   11490 		body = getVertexShaderBody();
   11491 		break;
   11492 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   11493 		body = getTessellationControlShaderBody();
   11494 		break;
   11495 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   11496 		body = getTessellationEvaluationShaderBody();
   11497 		break;
   11498 	case Utils::SHADER_STAGE_GEOMETRY:
   11499 		body = getGeometryShaderBody();
   11500 		break;
   11501 	case Utils::SHADER_STAGE_FRAGMENT:
   11502 		body = getFragmentShaderBody();
   11503 		break;
   11504 
   11505 	default:
   11506 	{
   11507 		TCU_FAIL("Unrecognized shader stage requested");
   11508 	}
   11509 	} /* switch (shader_stage) */
   11510 
   11511 	body_raw_ptr = body.c_str();
   11512 
   11513 	gl.shaderSource(m_so_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */);
   11514 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   11515 
   11516 	/* Try to compile the shader */
   11517 	glw::GLint compile_status = 0;
   11518 
   11519 	gl.compileShader(m_so_id);
   11520 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   11521 
   11522 	gl.getShaderiv(m_so_id, GL_COMPILE_STATUS, &compile_status);
   11523 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   11524 
   11525 	if (compile_status == GL_TRUE)
   11526 	{
   11527 		m_testCtx.getLog() << tcu::TestLog::Message << "The following shader was expected to fail to compile but was "
   11528 													   "accepted by the compiler:\n"
   11529 													   "\n"
   11530 						   << body.c_str() << tcu::TestLog::EndMessage;
   11531 
   11532 		m_has_test_passed = false;
   11533 	}
   11534 
   11535 	/* Good to release the shader at this point */
   11536 	gl.deleteShader(m_so_id);
   11537 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
   11538 }
   11539 
   11540 /** Retrieves body of a broken fragment shader.
   11541  *
   11542  *  @return Requested string.
   11543  **/
   11544 std::string NegativeTest3::getFragmentShaderBody() const
   11545 {
   11546 	return "#version 400\n"
   11547 		   "\n"
   11548 		   "#extension GL_ARB_shader_subroutine : require\n"
   11549 		   "\n"
   11550 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   11551 		   "\n"
   11552 		   "void testSubroutine1(inout vec4 test)\n"
   11553 		   "{\n"
   11554 		   "    test += vec4(3, 4, 5, 6);\n"
   11555 		   "}\n"
   11556 		   "\n"
   11557 		   "uniform testSubroutineType subroutineFunction;\n"
   11558 		   "out     vec4               result;\n"
   11559 		   "\n"
   11560 		   "void main()\n"
   11561 		   "{\n"
   11562 		   "    vec4 test = vec4(2, 3, 4, 5);\n"
   11563 		   "\n"
   11564 		   "    subroutineFunction(test);\n"
   11565 		   "\n"
   11566 		   "    result = test;\n"
   11567 		   "}\n";
   11568 }
   11569 
   11570 /** Retrieves body of a broken geometry shader.
   11571  *
   11572  *  @return Requested string.
   11573  **/
   11574 std::string NegativeTest3::getGeometryShaderBody() const
   11575 {
   11576 	return "#version 400\n"
   11577 		   "\n"
   11578 		   "#extension GL_ARB_shader_subroutine : require\n"
   11579 		   "\n"
   11580 		   "layout(points)                   in;\n"
   11581 		   "layout(points, max_vertices = 1) out;\n"
   11582 		   "\n"
   11583 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   11584 		   "\n"
   11585 		   "void testSubroutine1(inout vec4 test)\n"
   11586 		   "{\n"
   11587 		   "    test += vec4(3, 4, 5, 6);\n"
   11588 		   "}\n"
   11589 		   "\n"
   11590 		   "uniform testSubroutineType subroutineFunction;\n"
   11591 		   "\n"
   11592 		   "void main()\n"
   11593 		   "{\n"
   11594 		   "    vec4 test = vec4(2, 3, 4, 5);\n"
   11595 		   "\n"
   11596 		   "    subroutineFunction(test);\n"
   11597 		   "\n"
   11598 		   "    gl_Position = test;\n"
   11599 		   "    EmitVertex();\n"
   11600 		   "}\n";
   11601 }
   11602 
   11603 /** Retrieves body of a broken tessellation control shader.
   11604  *
   11605  *  @return Requested string.
   11606  **/
   11607 std::string NegativeTest3::getTessellationControlShaderBody() const
   11608 {
   11609 	return "#version 400\n"
   11610 		   "\n"
   11611 		   "#extension GL_ARB_shader_subroutine : require\n"
   11612 		   "\n"
   11613 		   "layout(vertices=4) out;\n"
   11614 		   "\n"
   11615 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   11616 		   "\n"
   11617 		   "void testSubroutine1(inout vec4 test)\n"
   11618 		   "{\n"
   11619 		   "    test += vec4(1, 2, 3, 4);\n"
   11620 		   "}\n"
   11621 		   "\n"
   11622 		   "uniform testSubroutineType subroutineFunction;\n"
   11623 		   "\n"
   11624 		   "void main()\n"
   11625 		   "{\n"
   11626 		   "    vec4 test = vec4(0, 1, 2, 3);\n"
   11627 		   "\n"
   11628 		   "    subroutineFunction(test);\n"
   11629 		   "\n"
   11630 		   "    gl_out[gl_InvocationID].gl_Position = test;\n"
   11631 		   "}\n";
   11632 }
   11633 
   11634 /** Retrieves body of a broken tessellation evaluation shader.
   11635  *
   11636  *  @return Requested string.
   11637  **/
   11638 std::string NegativeTest3::getTessellationEvaluationShaderBody() const
   11639 {
   11640 	return "#version 400\n"
   11641 		   "\n"
   11642 		   "#extension GL_ARB_shader_subroutine : require\n"
   11643 		   "\n"
   11644 		   "layout(quads) in;\n"
   11645 		   "\n"
   11646 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   11647 		   "\n"
   11648 		   "void testSubroutine1(inout vec4 test)\n"
   11649 		   "{\n"
   11650 		   "    test += vec4(2, 3, 4, 5);\n"
   11651 		   "}\n"
   11652 		   "\n"
   11653 		   "uniform testSubroutineType subroutineFunction;\n"
   11654 		   "\n"
   11655 		   "void main()\n"
   11656 		   "{\n"
   11657 		   "    vec4 test = vec4(1, 2, 3, 4);\n"
   11658 		   "\n"
   11659 		   "    subroutineFunction(test);\n"
   11660 		   "\n"
   11661 		   "    gl_Position = test;\n"
   11662 		   "}\n";
   11663 }
   11664 
   11665 /** Retrieves body of a broken vertex shader.
   11666  *
   11667  *  @return Requested string.
   11668  **/
   11669 std::string NegativeTest3::getVertexShaderBody() const
   11670 {
   11671 	return "#version 400\n"
   11672 		   "\n"
   11673 		   "#extension GL_ARB_shader_subroutine : require\n"
   11674 		   "\n"
   11675 		   "subroutine void testSubroutineType(inout vec4 test);\n"
   11676 		   "\n"
   11677 		   "void testSubroutine1(inout vec4 test)\n"
   11678 		   "{\n"
   11679 		   "    test += vec4(0, 1, 2, 3);\n"
   11680 		   "}\n"
   11681 		   "\n"
   11682 		   "uniform testSubroutineType subroutineFunction;\n"
   11683 		   "\n"
   11684 		   "void main()\n"
   11685 		   "{\n"
   11686 		   "    subroutineFunction(gl_Position);\n"
   11687 		   "}\n";
   11688 }
   11689 
   11690 /** Executes test iteration.
   11691  *
   11692  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   11693  */
   11694 tcu::TestNode::IterateResult NegativeTest3::iterate()
   11695 {
   11696 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   11697 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   11698 	{
   11699 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   11700 	}
   11701 
   11702 	/* Iterate over all shader stages */
   11703 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   11704 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   11705 	{
   11706 		executeTest(static_cast<Utils::_shader_stage>(shader_stage));
   11707 	} /* for (all shader stages) */
   11708 
   11709 	/* Done */
   11710 	if (m_has_test_passed)
   11711 	{
   11712 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   11713 	}
   11714 	else
   11715 	{
   11716 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   11717 	}
   11718 
   11719 	return STOP;
   11720 }
   11721 
   11722 /** Constructor.
   11723  *
   11724  *  @param context Rendering context.
   11725  *
   11726  **/
   11727 NegativeTest4::NegativeTest4(deqp::Context& context)
   11728 	: TestCase(context, "subroutines_incompatible_with_subroutine_type",
   11729 			   "Verifies that a compile-time error is generated when arguments and "
   11730 			   "return type do not match beween the function and each associated "
   11731 			   "subroutine type.")
   11732 	, m_has_test_passed(true)
   11733 	, m_so_id(0)
   11734 {
   11735 	/* Left blank intentionally */
   11736 }
   11737 
   11738 /** Deinitializes GL objects that may have been created during test
   11739  *  execution.
   11740  **/
   11741 void NegativeTest4::deinit()
   11742 {
   11743 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11744 
   11745 	if (m_so_id != 0)
   11746 	{
   11747 		gl.deleteShader(m_so_id);
   11748 
   11749 		m_so_id = 0;
   11750 	}
   11751 }
   11752 
   11753 /** Retrieves body of a shader of user-specified type that should be used
   11754  *  for a single test iteration. The shader will define user-specified number
   11755  *  of subroutine types, with the last type either defining an additional argument
   11756  *  or using a different return type.
   11757  *  A subroutine (claimed compatible with *all* subroutine types) will also be
   11758  *  defined in the shader.
   11759  *
   11760  *  @param shader_stage       Shader stage to use for the query.
   11761  *  @param n_subroutine_types Overall number of subroutine types that will be
   11762  *                            declared & used in the shader. Please see description
   11763  *                            for more details.
   11764  *
   11765  *  @return Requested string.
   11766  **/
   11767 std::string NegativeTest4::getShaderBody(const Utils::_shader_stage& shader_stage,
   11768 										 const unsigned int& n_subroutine_types, const _test_case& test_case) const
   11769 {
   11770 	std::stringstream result_sstream;
   11771 
   11772 	/* Form the pre-amble */
   11773 	result_sstream << "#version 400\n"
   11774 					  "\n"
   11775 					  "#extension GL_ARB_shader_subroutine : require\n"
   11776 					  "\n";
   11777 
   11778 	/* Inject stage-specific code */
   11779 	switch (shader_stage)
   11780 	{
   11781 	case Utils::SHADER_STAGE_GEOMETRY:
   11782 	{
   11783 		result_sstream << "layout (points) in;\n"
   11784 						  "layout (points, max_vertices = 1) out;\n"
   11785 						  "\n";
   11786 
   11787 		break;
   11788 	}
   11789 
   11790 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   11791 	{
   11792 		result_sstream << "layout (vertices = 4) out;\n"
   11793 						  "\n";
   11794 
   11795 		break;
   11796 	}
   11797 
   11798 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   11799 	{
   11800 		result_sstream << "layout (quads) in;\n"
   11801 						  "\n";
   11802 
   11803 		break;
   11804 	}
   11805 
   11806 	default:
   11807 		break;
   11808 	} /* switch (shader_stage) */
   11809 
   11810 	/* Insert subroutine type declarations */
   11811 	for (unsigned int n_subroutine_type = 0; n_subroutine_type < n_subroutine_types - 1; ++n_subroutine_type)
   11812 	{
   11813 		result_sstream << "subroutine void subroutineType" << n_subroutine_type << "(inout vec3 argument);\n";
   11814 	} /* for (all subroutine types) */
   11815 
   11816 	switch (test_case)
   11817 	{
   11818 	case TEST_CASE_INCOMPATIBLE_ARGUMENT_LIST:
   11819 	{
   11820 		result_sstream << "subroutine void subroutineType" << (n_subroutine_types - 1)
   11821 					   << "(inout vec3 argument, out vec4 argument2);\n";
   11822 
   11823 		break;
   11824 	}
   11825 
   11826 	case TEST_CASE_INCOMPATIBLE_RETURN_TYPE:
   11827 	{
   11828 		result_sstream << "subroutine int subroutineType" << (n_subroutine_types - 1) << "(inout vec3 argument);\n";
   11829 
   11830 		break;
   11831 	}
   11832 
   11833 	default:
   11834 	{
   11835 		TCU_FAIL("Unrecognized test case");
   11836 	}
   11837 	} /* switch (test_case) */
   11838 
   11839 	/* Insert subroutine declarations */
   11840 	result_sstream << "subroutine(";
   11841 
   11842 	for (unsigned int n_subroutine_type = 0; n_subroutine_type < n_subroutine_types; ++n_subroutine_type)
   11843 	{
   11844 		result_sstream << "subroutineType" << n_subroutine_type;
   11845 
   11846 		if (n_subroutine_type != (n_subroutine_types - 1))
   11847 		{
   11848 			result_sstream << ", ";
   11849 		}
   11850 	} /* for (all subroutine types) */
   11851 
   11852 	result_sstream << ") void function(inout vec3 argument)\n"
   11853 					  "{\n"
   11854 					  "    argument = vec3(1, 2, 3);\n"
   11855 					  "}\n"
   11856 					  "\n";
   11857 
   11858 	/* Insert remaining required stage-specific bits */
   11859 	switch (shader_stage)
   11860 	{
   11861 	case Utils::SHADER_STAGE_FRAGMENT:
   11862 	{
   11863 		result_sstream << "out vec4 result;\n"
   11864 						  "\n"
   11865 						  "void main()\n"
   11866 						  "{\n"
   11867 						  "    result = vec4(1, 2, 3, 4);\n"
   11868 						  "}\n";
   11869 
   11870 		break;
   11871 	}
   11872 
   11873 	case Utils::SHADER_STAGE_GEOMETRY:
   11874 	{
   11875 		result_sstream << "void main()\n"
   11876 						  "{\n"
   11877 						  "    gl_Position = vec4(1, 2, 3, 4);\n"
   11878 						  "    EmitVertex();\n"
   11879 						  "}\n";
   11880 
   11881 		break;
   11882 	}
   11883 
   11884 	case Utils::SHADER_STAGE_TESSELLATION_CONTROL:
   11885 	{
   11886 		result_sstream << "void main()\n"
   11887 						  "{\n"
   11888 						  "    gl_TessLevelInner[0]                = 1;\n"
   11889 						  "    gl_TessLevelInner[1]                = 1;\n"
   11890 						  "    gl_TessLevelOuter[0]                = 1;\n"
   11891 						  "    gl_TessLevelOuter[1]                = 1;\n"
   11892 						  "    gl_TessLevelOuter[2]                = 1;\n"
   11893 						  "    gl_TessLevelOuter[3]                = 1;\n"
   11894 						  "    gl_out[gl_InvocationID].gl_Position = vec4(2, 3, 4, 5);\n"
   11895 						  "}\n";
   11896 
   11897 		break;
   11898 	}
   11899 
   11900 	case Utils::SHADER_STAGE_TESSELLATION_EVALUATION:
   11901 	case Utils::SHADER_STAGE_VERTEX:
   11902 	{
   11903 		result_sstream << "void main()\n"
   11904 						  "{\n"
   11905 						  "    gl_Position = vec4(1, 2, 3, 4);\n"
   11906 						  "}\n";
   11907 
   11908 		break;
   11909 	}
   11910 
   11911 	default:
   11912 	{
   11913 		TCU_FAIL("Unrecognized shader stage");
   11914 	}
   11915 	} /* switch (shader_stage) */
   11916 
   11917 	return result_sstream.str();
   11918 }
   11919 
   11920 /** Executes test iteration.
   11921  *
   11922  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   11923  */
   11924 tcu::TestNode::IterateResult NegativeTest4::iterate()
   11925 {
   11926 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   11927 
   11928 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   11929 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   11930 	{
   11931 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   11932 	}
   11933 
   11934 	/* Iterate over all shader stages.. */
   11935 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   11936 		 shader_stage != static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   11937 	{
   11938 		/* For each shader stage, we will be trying to compile a number of invalid shaders.
   11939 		 * Each shader defines N different subroutine types. (N-1) of them are compatible
   11940 		 * with a subroutine, but exactly 1 will be mismatched. The test passes if GLSL
   11941 		 * compiler correctly detects that all shaders we will be trying to compile are
   11942 		 * broken.
   11943 		 */
   11944 		const glw::GLenum shader_type = Utils::getGLenumForShaderStage(static_cast<Utils::_shader_stage>(shader_stage));
   11945 
   11946 		for (unsigned int n_subroutine_types = 1; n_subroutine_types < 6; /* arbitrary number */
   11947 			 ++n_subroutine_types)
   11948 		{
   11949 			for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT);
   11950 				 ++test_case)
   11951 			{
   11952 				std::string body;
   11953 				const char* body_raw_ptr   = NULL;
   11954 				glw::GLint  compile_status = GL_FALSE;
   11955 
   11956 				body = getShaderBody(static_cast<Utils::_shader_stage>(shader_stage), n_subroutine_types,
   11957 									 static_cast<_test_case>(test_case));
   11958 				body_raw_ptr = body.c_str();
   11959 
   11960 				/* Try to compile the shader */
   11961 				m_so_id = gl.createShader(shader_type);
   11962 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed");
   11963 
   11964 				gl.shaderSource(m_so_id, 1 /* count */, &body_raw_ptr, DE_NULL);
   11965 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
   11966 
   11967 				gl.compileShader(m_so_id);
   11968 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
   11969 
   11970 				gl.getShaderiv(m_so_id, GL_COMPILE_STATUS, &compile_status);
   11971 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   11972 
   11973 				if (compile_status == GL_TRUE)
   11974 				{
   11975 					m_testCtx.getLog() << tcu::TestLog::Message << "A malformed "
   11976 									   << Utils::getShaderStageString(static_cast<Utils::_shader_stage>(shader_stage))
   11977 									   << " compiled successfully "
   11978 										  "("
   11979 									   << n_subroutine_types << " subroutine types "
   11980 																"were defined)."
   11981 									   << tcu::TestLog::EndMessage;
   11982 
   11983 					m_has_test_passed = false;
   11984 				}
   11985 
   11986 				/* Release the object */
   11987 				gl.deleteShader(m_so_id);
   11988 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader() call failed.");
   11989 			} /* for (all test cases) */
   11990 		}	 /* for (a number of different subroutine type declarations) */
   11991 	}		  /* for (all shader stages) */
   11992 
   11993 	/* Done */
   11994 	if (m_has_test_passed)
   11995 	{
   11996 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   11997 	}
   11998 	else
   11999 	{
   12000 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12001 	}
   12002 
   12003 	return STOP;
   12004 }
   12005 
   12006 /** Constructor.
   12007  *
   12008  *  @param context Rendering context.
   12009  *
   12010  **/
   12011 NegativeTest5::NegativeTest5(deqp::Context& context)
   12012 	: TestCase(context, "subroutine_uniform_wo_matching_subroutines",
   12013 			   "Verifies that a link- or compile-time error occurs when "
   12014 			   "trying to link a program with no subroutine for subroutine "
   12015 			   "uniform variable.")
   12016 	, m_fs_id(0)
   12017 	, m_gs_id(0)
   12018 	, m_has_test_passed(true)
   12019 	, m_po_id(0)
   12020 	, m_tc_id(0)
   12021 	, m_te_id(0)
   12022 	, m_vs_id(0)
   12023 {
   12024 	/* Left blank intentionally */
   12025 }
   12026 
   12027 /** Deinitializes all GL objects that may have been created during test execution */
   12028 void NegativeTest5::deinit()
   12029 {
   12030 	deinitIteration();
   12031 }
   12032 
   12033 /** Deinitializes all GL objects that may have been created during a single test
   12034  *  iteration.
   12035  ***/
   12036 void NegativeTest5::deinitIteration()
   12037 {
   12038 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12039 
   12040 	if (m_fs_id != 0)
   12041 	{
   12042 		gl.deleteShader(m_fs_id);
   12043 
   12044 		m_fs_id = 0;
   12045 	}
   12046 
   12047 	if (m_gs_id != 0)
   12048 	{
   12049 		gl.deleteShader(m_gs_id);
   12050 
   12051 		m_gs_id = 0;
   12052 	}
   12053 
   12054 	if (m_po_id != 0)
   12055 	{
   12056 		gl.deleteProgram(m_po_id);
   12057 
   12058 		m_po_id = 0;
   12059 	}
   12060 
   12061 	if (m_tc_id != 0)
   12062 	{
   12063 		gl.deleteShader(m_tc_id);
   12064 
   12065 		m_tc_id = 0;
   12066 	}
   12067 
   12068 	if (m_te_id != 0)
   12069 	{
   12070 		gl.deleteShader(m_te_id);
   12071 
   12072 		m_te_id = 0;
   12073 	}
   12074 
   12075 	if (m_vs_id != 0)
   12076 	{
   12077 		gl.deleteShader(m_vs_id);
   12078 
   12079 		m_vs_id = 0;
   12080 	}
   12081 }
   12082 
   12083 /** Executes a single test iteration.
   12084  *
   12085  *  If the iteration fails, m_has_test_passed will be set to false.
   12086  *
   12087  *  @param shader_stage Shader stage, for which a subroutine uniform should be
   12088  *                      declared in the shader without a matching subroutine.
   12089  **/
   12090 void NegativeTest5::executeIteration(const Utils::_shader_stage& shader_stage)
   12091 {
   12092 	std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   12093 	std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   12094 	std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   12095 	std::string te_body =
   12096 		getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   12097 	std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX);
   12098 
   12099 	if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body,
   12100 							DE_NULL, /* xfb_varyings */
   12101 							DE_NULL, /* n_xfb_varyings */
   12102 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   12103 	{
   12104 		/* None of the test programs should ever build successfully */
   12105 		m_testCtx.getLog() << tcu::TestLog::Message
   12106 						   << "A program object, consisting of the following shaders, has linked"
   12107 							  " correctly. One of the shaders defines a subroutine uniform but does "
   12108 							  "not implement any function that matches subroutine type of the uniform."
   12109 							  " This should have resulted in a compilation/link-time error.\n"
   12110 							  "\n"
   12111 							  "Vertex shader:\n"
   12112 							  "\n"
   12113 						   << vs_body << "\n"
   12114 										 "Tessellation control shader:\n"
   12115 										 "\n"
   12116 						   << tc_body << "\n"
   12117 										 "Tessellation evaluation shader:\n"
   12118 										 "\n"
   12119 						   << te_body << "\n"
   12120 										 "Geometry shader:\n"
   12121 										 "\n"
   12122 						   << gs_body << "\n"
   12123 										 "Fragment shader:\n"
   12124 										 "\n"
   12125 						   << fs_body << tcu::TestLog::EndMessage;
   12126 
   12127 		m_has_test_passed = false;
   12128 	}
   12129 }
   12130 
   12131 /** Retrieves fragment shader body.
   12132  *
   12133  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   12134  *                                                        a subroutine uniform without
   12135  *                                                        a matching subroutine, false otherwise.
   12136  *
   12137  *  @return Requested string.
   12138  **/
   12139 std::string NegativeTest5::getFragmentShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   12140 {
   12141 	std::stringstream result_sstream;
   12142 
   12143 	result_sstream << "#version 400\n"
   12144 					  "\n"
   12145 					  "#extension GL_ARB_shader_subroutine : require\n"
   12146 					  "\n";
   12147 
   12148 	if (include_invalid_subroutine_uniform_declaration)
   12149 	{
   12150 		result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n"
   12151 						  "\n"
   12152 						  "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n";
   12153 	};
   12154 
   12155 	result_sstream << "\n"
   12156 					  "out vec4 result;\n"
   12157 					  "\n"
   12158 					  "void main()\n"
   12159 					  "{\n";
   12160 
   12161 	if (include_invalid_subroutine_uniform_declaration)
   12162 	{
   12163 		result_sstream << "    test_subroutineFS(result);\n";
   12164 	}
   12165 	else
   12166 	{
   12167 		result_sstream << "    result = vec4(0, 1, 2, 3);\n";
   12168 	}
   12169 
   12170 	result_sstream << "}\n";
   12171 
   12172 	return result_sstream.str();
   12173 }
   12174 
   12175 /** Retrieves geometry shader body.
   12176  *
   12177  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   12178  *                                                        a subroutine uniform without
   12179  *                                                        a matching subroutine, false otherwise.
   12180  *
   12181  *  @return Requested string.
   12182  **/
   12183 std::string NegativeTest5::getGeometryShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   12184 {
   12185 	std::stringstream result_sstream;
   12186 
   12187 	result_sstream << "#version 400\n"
   12188 					  "\n"
   12189 					  "#extension GL_ARB_shader_subroutine : require\n"
   12190 					  "\n"
   12191 					  "layout (points)                   in;\n"
   12192 					  "layout (points, max_vertices = 1) out;\n"
   12193 					  "\n";
   12194 
   12195 	if (include_invalid_subroutine_uniform_declaration)
   12196 	{
   12197 		result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n"
   12198 						  "\n"
   12199 						  "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n";
   12200 	};
   12201 
   12202 	result_sstream << "\n"
   12203 					  "void main()\n"
   12204 					  "{\n";
   12205 
   12206 	if (include_invalid_subroutine_uniform_declaration)
   12207 	{
   12208 		result_sstream << "    test_subroutineGS(gl_Position);\n";
   12209 	}
   12210 	else
   12211 	{
   12212 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12213 	}
   12214 
   12215 	result_sstream << "EmitVertex();\n"
   12216 					  "}\n";
   12217 
   12218 	return result_sstream.str();
   12219 }
   12220 
   12221 /** Retrieves tessellation control shader body.
   12222  *
   12223  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   12224  *                                                        a subroutine uniform without
   12225  *                                                        a matching subroutine, false otherwise.
   12226  *
   12227  *  @return Requested string.
   12228  **/
   12229 std::string NegativeTest5::getTessellationControlShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   12230 {
   12231 	std::stringstream result_sstream;
   12232 
   12233 	result_sstream << "#version 400\n"
   12234 					  "\n"
   12235 					  "#extension GL_ARB_shader_subroutine : require\n"
   12236 					  "\n"
   12237 					  "layout (vertices = 4) out;\n"
   12238 					  "\n";
   12239 
   12240 	if (include_invalid_subroutine_uniform_declaration)
   12241 	{
   12242 		result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n"
   12243 						  "\n"
   12244 						  "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n";
   12245 	};
   12246 
   12247 	result_sstream << "\n"
   12248 					  "void main()\n"
   12249 					  "{\n";
   12250 
   12251 	if (include_invalid_subroutine_uniform_declaration)
   12252 	{
   12253 		result_sstream << "    test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n";
   12254 	}
   12255 	else
   12256 	{
   12257 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n";
   12258 	}
   12259 
   12260 	result_sstream << "}\n";
   12261 
   12262 	return result_sstream.str();
   12263 }
   12264 
   12265 /** Retrieves tessellation evaluation body.
   12266  *
   12267  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   12268  *                                                        a subroutine uniform without
   12269  *                                                        a matching subroutine, false otherwise.
   12270  *
   12271  *  @return Requested string.
   12272  **/
   12273 std::string NegativeTest5::getTessellationEvaluationShaderBody(
   12274 	bool include_invalid_subroutine_uniform_declaration) const
   12275 {
   12276 	std::stringstream result_sstream;
   12277 
   12278 	result_sstream << "#version 400\n"
   12279 					  "\n"
   12280 					  "#extension GL_ARB_shader_subroutine : require\n"
   12281 					  "\n"
   12282 					  "layout (quads) in;\n"
   12283 					  "\n";
   12284 
   12285 	if (include_invalid_subroutine_uniform_declaration)
   12286 	{
   12287 		result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n"
   12288 						  "\n"
   12289 						  "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n";
   12290 	};
   12291 
   12292 	result_sstream << "\n"
   12293 					  "void main()\n"
   12294 					  "{\n";
   12295 
   12296 	if (include_invalid_subroutine_uniform_declaration)
   12297 	{
   12298 		result_sstream << "    test_subroutineTE(gl_Position);\n";
   12299 	}
   12300 	else
   12301 	{
   12302 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12303 	}
   12304 
   12305 	result_sstream << "}\n";
   12306 
   12307 	return result_sstream.str();
   12308 }
   12309 
   12310 /** Retrieves vertex shader body.
   12311  *
   12312  *  @param include_invalid_subroutine_uniform_declaration true if the shader should declare
   12313  *                                                        a subroutine uniform without
   12314  *                                                        a matching subroutine, false otherwise.
   12315  *
   12316  *  @return Requested string.
   12317  **/
   12318 std::string NegativeTest5::getVertexShaderBody(bool include_invalid_subroutine_uniform_declaration) const
   12319 {
   12320 	std::stringstream result_sstream;
   12321 
   12322 	result_sstream << "#version 400\n"
   12323 					  "\n"
   12324 					  "#extension GL_ARB_shader_subroutine : require\n"
   12325 					  "\n";
   12326 
   12327 	if (include_invalid_subroutine_uniform_declaration)
   12328 	{
   12329 		result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n"
   12330 						  "\n"
   12331 						  "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n";
   12332 	};
   12333 
   12334 	result_sstream << "\n"
   12335 					  "void main()\n"
   12336 					  "{\n";
   12337 
   12338 	if (include_invalid_subroutine_uniform_declaration)
   12339 	{
   12340 		result_sstream << "    test_subroutineVS(gl_Position);\n";
   12341 	}
   12342 	else
   12343 	{
   12344 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12345 	}
   12346 
   12347 	result_sstream << "}\n";
   12348 
   12349 	return result_sstream.str();
   12350 }
   12351 
   12352 /** Executes test iteration.
   12353  *
   12354  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12355  */
   12356 tcu::TestNode::IterateResult NegativeTest5::iterate()
   12357 {
   12358 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   12359 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   12360 	{
   12361 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   12362 	}
   12363 
   12364 	/* Iterate over all shader stages. Iteration-specific shader stage defines a subroutine type &
   12365 	 * a corresponding subroutine uniform, for which no compatible subroutines are available. All
   12366 	 * other shader stages are defined correctly.
   12367 	 */
   12368 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   12369 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   12370 	{
   12371 		executeIteration(static_cast<Utils::_shader_stage>(shader_stage));
   12372 		deinitIteration();
   12373 	} /* for (all shader stages) */
   12374 
   12375 	/* All done */
   12376 	if (m_has_test_passed)
   12377 	{
   12378 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12379 	}
   12380 	else
   12381 	{
   12382 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12383 	}
   12384 
   12385 	return STOP;
   12386 }
   12387 
   12388 /** Constructor.
   12389  *
   12390  *  @param context Rendering context.
   12391  *
   12392  **/
   12393 NegativeTest6::NegativeTest6(deqp::Context& context)
   12394 	: TestCase(context, "two_duplicate_functions_one_being_a_subroutine",
   12395 			   "Verifies that a link- or compile-time error occurs if any shader in "
   12396 			   "a program object includes two functions with the same name and one "
   12397 			   "of which is associated with a subroutine type.")
   12398 	, m_fs_id(0)
   12399 	, m_gs_id(0)
   12400 	, m_has_test_passed(true)
   12401 	, m_po_id(0)
   12402 	, m_tc_id(0)
   12403 	, m_te_id(0)
   12404 	, m_vs_id(0)
   12405 {
   12406 	/* Left blank intentionally */
   12407 }
   12408 
   12409 /** Deinitializes all GL objects that may have been created during test execution */
   12410 void NegativeTest6::deinit()
   12411 {
   12412 	deinitIteration();
   12413 }
   12414 
   12415 /** Deinitializes all GL objects that may have been created during a single test
   12416  *  iteration.
   12417  ***/
   12418 void NegativeTest6::deinitIteration()
   12419 {
   12420 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12421 
   12422 	if (m_fs_id != 0)
   12423 	{
   12424 		gl.deleteShader(m_fs_id);
   12425 
   12426 		m_fs_id = 0;
   12427 	}
   12428 
   12429 	if (m_gs_id != 0)
   12430 	{
   12431 		gl.deleteShader(m_gs_id);
   12432 
   12433 		m_gs_id = 0;
   12434 	}
   12435 
   12436 	if (m_po_id != 0)
   12437 	{
   12438 		gl.deleteProgram(m_po_id);
   12439 
   12440 		m_po_id = 0;
   12441 	}
   12442 
   12443 	if (m_tc_id != 0)
   12444 	{
   12445 		gl.deleteShader(m_tc_id);
   12446 
   12447 		m_tc_id = 0;
   12448 	}
   12449 
   12450 	if (m_te_id != 0)
   12451 	{
   12452 		gl.deleteShader(m_te_id);
   12453 
   12454 		m_te_id = 0;
   12455 	}
   12456 
   12457 	if (m_vs_id != 0)
   12458 	{
   12459 		gl.deleteShader(m_vs_id);
   12460 
   12461 		m_vs_id = 0;
   12462 	}
   12463 }
   12464 
   12465 /** Executes a single test iteration.
   12466  *
   12467  *  If the iteration fails, m_has_test_passed will be set to false.
   12468  *
   12469  *  @param shader_stage Shader stage, for which two duplicate functions
   12470  *                      (one additionally marked as subroutine) should
   12471  *                      be defined.
   12472  **/
   12473 void NegativeTest6::executeIteration(const Utils::_shader_stage& shader_stage)
   12474 {
   12475 	std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   12476 	std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   12477 	std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   12478 	std::string te_body =
   12479 		getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   12480 	std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX);
   12481 
   12482 	if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body,
   12483 							DE_NULL, /* xfb_varyings */
   12484 							DE_NULL, /* n_xfb_varyings */
   12485 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   12486 	{
   12487 		/* None of the test programs should ever build successfully */
   12488 		m_testCtx.getLog() << tcu::TestLog::Message
   12489 						   << "A program object, consisting of the following shaders, has linked"
   12490 							  " correctly. This is invalid, because one of the shaders defines two"
   12491 							  " functions with the same name, with an exception that one of the"
   12492 							  " functions is marked as a subroutine.\n"
   12493 							  "\n"
   12494 							  "Vertex shader:\n"
   12495 							  "\n"
   12496 						   << vs_body << "\n"
   12497 										 "Tessellation control shader:\n"
   12498 										 "\n"
   12499 						   << tc_body << "\n"
   12500 										 "Tessellation evaluation shader:\n"
   12501 										 "\n"
   12502 						   << te_body << "\n"
   12503 										 "Geometry shader:\n"
   12504 										 "\n"
   12505 						   << gs_body << "\n"
   12506 										 "Fragment shader:\n"
   12507 										 "\n"
   12508 						   << fs_body << tcu::TestLog::EndMessage;
   12509 
   12510 		m_has_test_passed = false;
   12511 	}
   12512 }
   12513 
   12514 /** Retrieves fragment shader body.
   12515  *
   12516  *  @param include_invalid_declaration true if the shader should include duplicate function
   12517  *                                     declaration.
   12518  *
   12519  *  @return Requested string.
   12520  **/
   12521 std::string NegativeTest6::getFragmentShaderBody(bool include_invalid_declaration) const
   12522 {
   12523 	std::stringstream result_sstream;
   12524 
   12525 	result_sstream << "#version 400\n"
   12526 					  "\n"
   12527 					  "#extension GL_ARB_shader_subroutine : require\n"
   12528 					  "\n";
   12529 
   12530 	if (include_invalid_declaration)
   12531 	{
   12532 		result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n"
   12533 						  "\n"
   12534 						  "subroutine(subroutineTestTypeFS) void test_impl1(out vec4 test)\n"
   12535 						  "{\n"
   12536 						  "    test = vec4(1, 2, 3, 4);\n"
   12537 						  "}\n"
   12538 						  "\n"
   12539 						  "void test_impl1(out vec4 test)\n"
   12540 						  "{\n"
   12541 						  "    test = vec4(2, 3, 4, 5);\n"
   12542 						  "}\n"
   12543 						  "\n"
   12544 						  "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n";
   12545 	};
   12546 
   12547 	result_sstream << "\n"
   12548 					  "out vec4 result;\n"
   12549 					  "\n"
   12550 					  "void main()\n"
   12551 					  "{\n";
   12552 
   12553 	if (include_invalid_declaration)
   12554 	{
   12555 		result_sstream << "    test_subroutineFS(result);\n";
   12556 	}
   12557 	else
   12558 	{
   12559 		result_sstream << "    result = vec4(0, 1, 2, 3);\n";
   12560 	}
   12561 
   12562 	result_sstream << "}\n";
   12563 
   12564 	return result_sstream.str();
   12565 }
   12566 
   12567 /** Retrieves geometry shader body.
   12568  *
   12569  *  @param include_invalid_declaration true if the shader should include duplicate function
   12570  *                                     declaration.
   12571  *
   12572  *  @return Requested string.
   12573  **/
   12574 std::string NegativeTest6::getGeometryShaderBody(bool include_invalid_declaration) const
   12575 {
   12576 	std::stringstream result_sstream;
   12577 
   12578 	result_sstream << "#version 400\n"
   12579 					  "\n"
   12580 					  "#extension GL_ARB_shader_subroutine : require\n"
   12581 					  "\n"
   12582 					  "layout (points)                   in;\n"
   12583 					  "layout (points, max_vertices = 1) out;\n"
   12584 					  "\n";
   12585 
   12586 	if (include_invalid_declaration)
   12587 	{
   12588 		result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n"
   12589 						  "\n"
   12590 						  "subroutine(subroutineTestTypeGS) void test_impl1(out vec4 test)\n"
   12591 						  "{\n"
   12592 						  "    test = vec4(1, 2, 3, 4);\n"
   12593 						  "}\n"
   12594 						  "\n"
   12595 						  "void test_impl1(out vec4 test)\n"
   12596 						  "{\n"
   12597 						  "    test = vec4(2, 3, 4, 5);\n"
   12598 						  "}\n"
   12599 						  "\n"
   12600 						  "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n";
   12601 	};
   12602 
   12603 	result_sstream << "\n"
   12604 					  "void main()\n"
   12605 					  "{\n";
   12606 
   12607 	if (include_invalid_declaration)
   12608 	{
   12609 		result_sstream << "    test_subroutineGS(gl_Position);\n";
   12610 	}
   12611 	else
   12612 	{
   12613 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12614 	}
   12615 
   12616 	result_sstream << "EmitVertex();\n"
   12617 					  "}\n";
   12618 
   12619 	return result_sstream.str();
   12620 }
   12621 
   12622 /** Retrieves tessellation control shader body.
   12623  *
   12624  *  @param include_invalid_declaration true if the shader should include duplicate function
   12625  *                                     declaration.
   12626  *
   12627  *  @return Requested string.
   12628  **/
   12629 std::string NegativeTest6::getTessellationControlShaderBody(bool include_invalid_declaration) const
   12630 {
   12631 	std::stringstream result_sstream;
   12632 
   12633 	result_sstream << "#version 400\n"
   12634 					  "\n"
   12635 					  "#extension GL_ARB_shader_subroutine : require\n"
   12636 					  "\n"
   12637 					  "layout (vertices = 4) out;\n"
   12638 					  "\n";
   12639 
   12640 	if (include_invalid_declaration)
   12641 	{
   12642 		result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n"
   12643 						  "\n"
   12644 						  "subroutine(subroutineTestTypeTC) void test_impl1(out vec4 test)\n"
   12645 						  "{\n"
   12646 						  "    test = vec4(1, 2, 3, 4);\n"
   12647 						  "}\n"
   12648 						  "\n"
   12649 						  "void test_impl1(out vec4 test)\n"
   12650 						  "{\n"
   12651 						  "    test = vec4(2, 3, 4, 5);\n"
   12652 						  "}\n"
   12653 						  "\n"
   12654 						  "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n";
   12655 	};
   12656 
   12657 	result_sstream << "\n"
   12658 					  "void main()\n"
   12659 					  "{\n";
   12660 
   12661 	if (include_invalid_declaration)
   12662 	{
   12663 		result_sstream << "    test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n";
   12664 	}
   12665 	else
   12666 	{
   12667 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n";
   12668 	}
   12669 
   12670 	result_sstream << "}\n";
   12671 
   12672 	return result_sstream.str();
   12673 }
   12674 
   12675 /** Retrieves tessellation evaluation body.
   12676  *
   12677  *  @param include_invalid_declaration true if the shader should include duplicate function
   12678  *                                     declaration.
   12679  *
   12680  *  @return Requested string.
   12681  **/
   12682 std::string NegativeTest6::getTessellationEvaluationShaderBody(bool include_invalid_declaration) const
   12683 {
   12684 	std::stringstream result_sstream;
   12685 
   12686 	result_sstream << "#version 400\n"
   12687 					  "\n"
   12688 					  "#extension GL_ARB_shader_subroutine : require\n"
   12689 					  "\n"
   12690 					  "layout (quads) in;\n"
   12691 					  "\n";
   12692 
   12693 	if (include_invalid_declaration)
   12694 	{
   12695 		result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n"
   12696 						  "\n"
   12697 						  "subroutine(subroutineTestTypeTE) void test_impl1(out vec4 test)\n"
   12698 						  "{\n"
   12699 						  "    test = vec4(1, 2, 3, 4);\n"
   12700 						  "}\n"
   12701 						  "\n"
   12702 						  "void test_impl1(out vec4 test)\n"
   12703 						  "{\n"
   12704 						  "    test = vec4(2, 3, 4, 5);\n"
   12705 						  "}\n"
   12706 						  "\n"
   12707 						  "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n";
   12708 	};
   12709 
   12710 	result_sstream << "\n"
   12711 					  "void main()\n"
   12712 					  "{\n";
   12713 
   12714 	if (include_invalid_declaration)
   12715 	{
   12716 		result_sstream << "    test_subroutineTE(gl_Position);\n";
   12717 	}
   12718 	else
   12719 	{
   12720 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12721 	}
   12722 
   12723 	result_sstream << "}\n";
   12724 
   12725 	return result_sstream.str();
   12726 }
   12727 
   12728 /** Retrieves vertex shader body.
   12729  *
   12730  *  @param include_invalid_declaration true if the shader should include duplicate function
   12731  *                                     declaration.
   12732  *
   12733  *  @return Requested string.
   12734  **/
   12735 std::string NegativeTest6::getVertexShaderBody(bool include_invalid_declaration) const
   12736 {
   12737 	std::stringstream result_sstream;
   12738 
   12739 	result_sstream << "#version 400\n"
   12740 					  "\n"
   12741 					  "#extension GL_ARB_shader_subroutine : require\n"
   12742 					  "\n";
   12743 
   12744 	if (include_invalid_declaration)
   12745 	{
   12746 		result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n"
   12747 						  "\n"
   12748 						  "subroutine(subroutineTestTypeVS) void test_impl1(out vec4 test)\n"
   12749 						  "{\n"
   12750 						  "    test = vec4(1, 2, 3, 4);\n"
   12751 						  "}\n"
   12752 						  "\n"
   12753 						  "void test_impl1(out vec4 test)\n"
   12754 						  "{\n"
   12755 						  "    test = vec4(2, 3, 4, 5);\n"
   12756 						  "}\n"
   12757 						  "\n"
   12758 						  "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n";
   12759 	};
   12760 
   12761 	result_sstream << "\n"
   12762 					  "void main()\n"
   12763 					  "{\n";
   12764 
   12765 	if (include_invalid_declaration)
   12766 	{
   12767 		result_sstream << "    test_subroutineVS(gl_Position);\n";
   12768 	}
   12769 	else
   12770 	{
   12771 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   12772 	}
   12773 
   12774 	result_sstream << "}\n";
   12775 
   12776 	return result_sstream.str();
   12777 }
   12778 
   12779 /** Executes test iteration.
   12780  *
   12781  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12782  */
   12783 tcu::TestNode::IterateResult NegativeTest6::iterate()
   12784 {
   12785 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   12786 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   12787 	{
   12788 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   12789 	}
   12790 
   12791 	/* Iterate over all shader stages. In each iteration, we will inject invalid
   12792 	 * duplicate function declarations to iteration-specific shader stage. All other
   12793 	 * shader stages will be assigned valid bodies. Test should fail if the program
   12794 	 * links successfully.
   12795 	 */
   12796 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   12797 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   12798 	{
   12799 		executeIteration(static_cast<Utils::_shader_stage>(shader_stage));
   12800 		deinitIteration();
   12801 	} /* for (all shader stages) */
   12802 
   12803 	/* All done */
   12804 	if (m_has_test_passed)
   12805 	{
   12806 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12807 	}
   12808 	else
   12809 	{
   12810 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   12811 	}
   12812 
   12813 	return STOP;
   12814 }
   12815 
   12816 /** Constructor
   12817  *
   12818  * @param context CTS context
   12819  **/
   12820 NegativeTest7::NegativeTest7(deqp::Context& context)
   12821 	: TestCase(context, "recursion", "Verify that it is not possible to build program with recursing subroutines")
   12822 	, m_program_id(0)
   12823 	, m_vertex_shader_id(0)
   12824 {
   12825 	/* Nothing to be done here */
   12826 }
   12827 
   12828 /** Deinitializes all GL objects that may have been created during test execution
   12829  *
   12830  **/
   12831 void NegativeTest7::deinit()
   12832 {
   12833 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   12834 
   12835 	if (m_program_id != 0)
   12836 	{
   12837 		gl.deleteProgram(m_program_id);
   12838 
   12839 		m_program_id = 0;
   12840 	}
   12841 
   12842 	if (m_vertex_shader_id != 0)
   12843 	{
   12844 		gl.deleteShader(m_vertex_shader_id);
   12845 
   12846 		m_vertex_shader_id = 0;
   12847 	}
   12848 }
   12849 
   12850 /** Executes test iteration.
   12851  *
   12852  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   12853  **/
   12854 tcu::TestNode::IterateResult NegativeTest7::iterate()
   12855 {
   12856 	static const GLchar* vertex_shader_with_static_recursion =
   12857 		"#version 400\n"
   12858 		"\n"
   12859 		"#extension GL_ARB_shader_subroutine : require\n"
   12860 		"\n"
   12861 		"precision highp float;\n"
   12862 		"\n"
   12863 		"subroutine vec4 routine_type(in vec4 data, in uint control);\n"
   12864 		"\n"
   12865 		"subroutine (routine_type) vec4 power_routine(in vec4 data, in uint control)\n"
   12866 		"{\n"
   12867 		"    if (0 != control)\n"
   12868 		"    {\n"
   12869 		"        return data * power_routine(data, control - 1);\n"
   12870 		"    }\n"
   12871 		"    else\n"
   12872 		"    {\n"
   12873 		"        return vec4(1, 1, 1, 1);\n"
   12874 		"    }\n"
   12875 		"}\n"
   12876 		"\n"
   12877 		"subroutine (routine_type) vec4 select_routine(in vec4 data, in uint control)\n"
   12878 		"{\n"
   12879 		"    if (0 == control)\n"
   12880 		"    {\n"
   12881 		"        return data.rrrr;\n"
   12882 		"    }\n"
   12883 		"    else if (1 == control)\n"
   12884 		"    {\n"
   12885 		"        return data.gggg;\n"
   12886 		"    }\n"
   12887 		"    else if (2 == control)\n"
   12888 		"    {\n"
   12889 		"        return data.bbbb;\n"
   12890 		"    }\n"
   12891 		"    else\n"
   12892 		"    {\n"
   12893 		"        return data.aaaa;\n"
   12894 		"    }\n"
   12895 		"}\n"
   12896 		"\n"
   12897 		"subroutine uniform routine_type routine;\n"
   12898 		"\n"
   12899 		"uniform vec4 uni_value;\n"
   12900 		"uniform uint uni_control;\n"
   12901 		"\n"
   12902 		"out vec4 out_result;\n"
   12903 		"\n"
   12904 		"void main()\n"
   12905 		"{\n"
   12906 		"    out_result = routine(uni_value, uni_control);\n"
   12907 		"}\n"
   12908 		"\n";
   12909 
   12910 	static const GLchar* vertex_shader_with_dynamic_recursion =
   12911 		"#version 400\n"
   12912 		"\n"
   12913 		"#extension GL_ARB_shader_subroutine : require\n"
   12914 		"\n"
   12915 		"precision highp float;\n"
   12916 		"\n"
   12917 		"subroutine vec4 routine_type(in vec4 data);\n"
   12918 		"\n"
   12919 		"subroutine uniform routine_type routine;\n"
   12920 		"\n"
   12921 		"subroutine (routine_type) vec4 div_by_2(in vec4 data)\n"
   12922 		"{\n"
   12923 		"    return data / 2;\n"
   12924 		"}\n"
   12925 		"\n"
   12926 		"subroutine (routine_type) vec4 div_routine_result_by_2(in vec4 data)\n"
   12927 		"{\n"
   12928 		"    return routine(data) / 2;\n"
   12929 		"}\n"
   12930 		"\n"
   12931 		"uniform vec4 uni_value;\n"
   12932 		"\n"
   12933 		"out vec4 out_result;\n"
   12934 		"\n"
   12935 		"void main()\n"
   12936 		"{\n"
   12937 		"    out_result = routine(uni_value);\n"
   12938 		"}\n"
   12939 		"\n";
   12940 
   12941 	static const GLchar* vertex_shader_with_subroutine_function_recursion =
   12942 		"#version 400\n"
   12943 		"\n"
   12944 		"#extension GL_ARB_shader_subroutine : require\n"
   12945 		"\n"
   12946 		"precision highp float;\n"
   12947 		"\n"
   12948 		"subroutine vec4 routine_type(in vec4 data);\n"
   12949 		"\n"
   12950 		"subroutine uniform routine_type routine;\n"
   12951 		"\n"
   12952 		"vec4 function(in vec4 data)\n"
   12953 		"{\n"
   12954 		"    return routine(data) + vec4(0.5, 0.5, 0.5, 0.5);\n"
   12955 		"}\n"
   12956 		"\n"
   12957 		"subroutine (routine_type) vec4 routine_a(in vec4 data)\n"
   12958 		"{\n"
   12959 		"    return function(data) / 2;\n"
   12960 		"}\n"
   12961 		"\n"
   12962 		"subroutine (routine_type) vec4 routine_b(in vec4 data)\n"
   12963 		"{\n"
   12964 		"    return routine_a(data) * 2;\n"
   12965 		"}\n"
   12966 		"\n"
   12967 		"uniform vec4 uni_value;\n"
   12968 		"\n"
   12969 		"out vec4 out_result;\n"
   12970 		"\n"
   12971 		"void main()\n"
   12972 		"{\n"
   12973 		"    out_result = routine(uni_value);\n"
   12974 		"}\n"
   12975 		"\n";
   12976 
   12977 	bool result = true;
   12978 
   12979 	if (false == test(vertex_shader_with_subroutine_function_recursion, "routine_a"))
   12980 	{
   12981 		result = false;
   12982 	}
   12983 
   12984 	if (false == test(vertex_shader_with_dynamic_recursion, "div_routine_result_by_2"))
   12985 	{
   12986 		result = false;
   12987 	}
   12988 
   12989 	if (false == test(vertex_shader_with_static_recursion, "power_routine"))
   12990 	{
   12991 		result = false;
   12992 	}
   12993 
   12994 	/* Set result */
   12995 	if (true == result)
   12996 	{
   12997 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   12998 	}
   12999 	else
   13000 	{
   13001 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   13002 	}
   13003 
   13004 	/* Done */
   13005 	return tcu::TestNode::STOP;
   13006 }
   13007 
   13008 /** Try to build program from vertex shader code.
   13009  *
   13010  * @param vertex_shader_code        Source code of vertex shader
   13011  * @param name_of_recursive_routine Name of subroutine that should cause link failure due to recursion
   13012  *
   13013  * @return true build process failed, false otherwise
   13014  **/
   13015 bool NegativeTest7::test(const GLchar* vertex_shader_code, const GLchar* name_of_recursive_routine)
   13016 {
   13017 	const glw::Functions& gl		   = m_context.getRenderContext().getFunctions();
   13018 	bool				  result	   = true;
   13019 	static const GLchar*  varying_name = "out_result";
   13020 
   13021 	/* Try to build program */
   13022 	if (true == Utils::buildProgram(gl, vertex_shader_code, "", "", "", "", &varying_name /* varying_names */,
   13023 									1 /* n_varyings */, &m_vertex_shader_id, 0, 0, 0, 0, &m_program_id))
   13024 	{
   13025 		/* Success is considered an error */
   13026 
   13027 		Utils::program program(m_context);
   13028 		GLuint		   index = 0;
   13029 
   13030 		program.build(0, 0, 0, 0, 0, vertex_shader_code, 0, 0);
   13031 
   13032 		/* Verify that recursive subroutine is active */
   13033 		try
   13034 		{
   13035 			index = program.getSubroutineIndex(name_of_recursive_routine, GL_VERTEX_SHADER);
   13036 		}
   13037 		catch (const std::exception& exc)
   13038 		{
   13039 			/* Something wrong with shader or compilation */
   13040 			m_context.getTestContext().getLog()
   13041 				<< tcu::TestLog::Message << "It is expected that subroutine: \n"
   13042 				<< name_of_recursive_routine
   13043 				<< " is considered active. This subroutine is potentially recursive and should cause link failure."
   13044 				<< tcu::TestLog::EndMessage;
   13045 
   13046 			throw exc;
   13047 		}
   13048 
   13049 		/* Subsoutine is active, however linking should fail */
   13050 		m_context.getTestContext().getLog()
   13051 			<< tcu::TestLog::Message << "Error. Program with potentially recursive subroutine, "
   13052 			<< name_of_recursive_routine << ", which is active, index: " << index << ", has been built successfully.\n"
   13053 			<< vertex_shader_code << tcu::TestLog::EndMessage;
   13054 
   13055 		result = false;
   13056 	}
   13057 
   13058 	/* Delete program and shader */
   13059 	deinit();
   13060 
   13061 	/* Done */
   13062 	return result;
   13063 }
   13064 
   13065 /** Constructor.
   13066  *
   13067  *  @param context Rendering context.
   13068  *
   13069  **/
   13070 NegativeTest8::NegativeTest8(deqp::Context& context)
   13071 	: TestCase(context, "subroutine_wo_body", "Verifies that a compile- or link-time error occurs if a function "
   13072 											  "declared as a subroutine does not include a body.")
   13073 	, m_fs_id(0)
   13074 	, m_gs_id(0)
   13075 	, m_has_test_passed(true)
   13076 	, m_po_id(0)
   13077 	, m_tc_id(0)
   13078 	, m_te_id(0)
   13079 	, m_vs_id(0)
   13080 {
   13081 	/* Left blank intentionally */
   13082 }
   13083 
   13084 /** Deinitializes all GL objects that may have been created during test execution */
   13085 void NegativeTest8::deinit()
   13086 {
   13087 	deinitIteration();
   13088 }
   13089 
   13090 /** Deinitializes all GL objects that may have been created during a single test
   13091  *  iteration.
   13092  ***/
   13093 void NegativeTest8::deinitIteration()
   13094 {
   13095 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13096 
   13097 	if (m_fs_id != 0)
   13098 	{
   13099 		gl.deleteShader(m_fs_id);
   13100 
   13101 		m_fs_id = 0;
   13102 	}
   13103 
   13104 	if (m_gs_id != 0)
   13105 	{
   13106 		gl.deleteShader(m_gs_id);
   13107 
   13108 		m_gs_id = 0;
   13109 	}
   13110 
   13111 	if (m_po_id != 0)
   13112 	{
   13113 		gl.deleteProgram(m_po_id);
   13114 
   13115 		m_po_id = 0;
   13116 	}
   13117 
   13118 	if (m_tc_id != 0)
   13119 	{
   13120 		gl.deleteShader(m_tc_id);
   13121 
   13122 		m_tc_id = 0;
   13123 	}
   13124 
   13125 	if (m_te_id != 0)
   13126 	{
   13127 		gl.deleteShader(m_te_id);
   13128 
   13129 		m_te_id = 0;
   13130 	}
   13131 
   13132 	if (m_vs_id != 0)
   13133 	{
   13134 		gl.deleteShader(m_vs_id);
   13135 
   13136 		m_vs_id = 0;
   13137 	}
   13138 }
   13139 
   13140 /** Executes a single test iteration.
   13141  *
   13142  *  If the iteration fails, m_has_test_passed will be set to false.
   13143  *
   13144  *  @param shader_stage Shader stage, for which two duplicate functions
   13145  *                      (one additionally marked as subroutine) should
   13146  *                      be defined.
   13147  **/
   13148 void NegativeTest8::executeIteration(const Utils::_shader_stage& shader_stage)
   13149 {
   13150 	std::string fs_body = getFragmentShaderBody(shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   13151 	std::string gs_body = getGeometryShaderBody(shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   13152 	std::string tc_body = getTessellationControlShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   13153 	std::string te_body =
   13154 		getTessellationEvaluationShaderBody(shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   13155 	std::string vs_body = getVertexShaderBody(shader_stage == Utils::SHADER_STAGE_VERTEX);
   13156 
   13157 	if (Utils::buildProgram(m_context.getRenderContext().getFunctions(), vs_body, tc_body, te_body, gs_body, fs_body,
   13158 							DE_NULL, /* xfb_varyings */
   13159 							DE_NULL, /* n_xfb_varyings */
   13160 							&m_vs_id, &m_tc_id, &m_te_id, &m_gs_id, &m_fs_id, &m_po_id))
   13161 	{
   13162 		/* None of the test programs should ever build successfully */
   13163 		m_testCtx.getLog() << tcu::TestLog::Message
   13164 						   << "A program object consisting of FS+GS+TC+TE+VS stages has linked successfully, "
   13165 							  "even though one of the shaders only defines a subroutine that lacks any body."
   13166 							  "\n"
   13167 							  "Vertex shader:\n"
   13168 							  "\n"
   13169 						   << vs_body << "\n"
   13170 										 "Tessellation control shader:\n"
   13171 										 "\n"
   13172 						   << tc_body << "\n"
   13173 										 "Tessellation evaluation shader:\n"
   13174 										 "\n"
   13175 						   << te_body << "\n"
   13176 										 "Geometry shader:\n"
   13177 										 "\n"
   13178 						   << gs_body << "\n"
   13179 										 "Fragment shader:\n"
   13180 										 "\n"
   13181 						   << fs_body << tcu::TestLog::EndMessage;
   13182 
   13183 		m_has_test_passed = false;
   13184 	}
   13185 }
   13186 
   13187 /** Retrieves fragment shader body.
   13188  *
   13189  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   13190  *                                     the shader, false to skip it.
   13191  *
   13192  *  @return Requested string.
   13193  **/
   13194 std::string NegativeTest8::getFragmentShaderBody(bool include_invalid_declaration) const
   13195 {
   13196 	std::stringstream result_sstream;
   13197 
   13198 	result_sstream << "#version 400\n"
   13199 					  "\n"
   13200 					  "#extension GL_ARB_shader_subroutine : require\n"
   13201 					  "\n";
   13202 
   13203 	if (include_invalid_declaration)
   13204 	{
   13205 		result_sstream << "subroutine void subroutineTestTypeFS(out vec4 test);\n"
   13206 						  "\n"
   13207 						  "subroutine(subroutineTestTypeFS) void test_impl1(out vec4 test);\n"
   13208 						  "\n"
   13209 						  "subroutine uniform subroutineTestTypeFS test_subroutineFS;\n";
   13210 	};
   13211 
   13212 	result_sstream << "\n"
   13213 					  "out vec4 result;\n"
   13214 					  "\n"
   13215 					  "void main()\n"
   13216 					  "{\n";
   13217 
   13218 	if (include_invalid_declaration)
   13219 	{
   13220 		result_sstream << "    test_subroutineFS(result);\n";
   13221 	}
   13222 	else
   13223 	{
   13224 		result_sstream << "    result = vec4(0, 1, 2, 3);\n";
   13225 	}
   13226 
   13227 	result_sstream << "}\n";
   13228 
   13229 	return result_sstream.str();
   13230 }
   13231 
   13232 /** Retrieves geometry shader body.
   13233  *
   13234  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   13235  *                                     the shader, false to skip it.
   13236  *
   13237  *  @return Requested string.
   13238  **/
   13239 std::string NegativeTest8::getGeometryShaderBody(bool include_invalid_declaration) const
   13240 {
   13241 	std::stringstream result_sstream;
   13242 
   13243 	result_sstream << "#version 400\n"
   13244 					  "\n"
   13245 					  "#extension GL_ARB_shader_subroutine : require\n"
   13246 					  "\n"
   13247 					  "layout (points)                   in;\n"
   13248 					  "layout (points, max_vertices = 1) out;\n"
   13249 					  "\n";
   13250 
   13251 	if (include_invalid_declaration)
   13252 	{
   13253 		result_sstream << "subroutine void subroutineTestTypeGS(out vec4 test);\n"
   13254 						  "\n"
   13255 						  "subroutine(subroutineTestTypeGS) void test_impl1(out vec4 test);\n"
   13256 						  "\n"
   13257 						  "subroutine uniform subroutineTestTypeGS test_subroutineGS;\n";
   13258 	};
   13259 
   13260 	result_sstream << "\n"
   13261 					  "void main()\n"
   13262 					  "{\n";
   13263 
   13264 	if (include_invalid_declaration)
   13265 	{
   13266 		result_sstream << "    test_subroutineGS(gl_Position);\n";
   13267 	}
   13268 	else
   13269 	{
   13270 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   13271 	}
   13272 
   13273 	result_sstream << "EmitVertex();\n"
   13274 					  "}\n";
   13275 
   13276 	return result_sstream.str();
   13277 }
   13278 
   13279 /** Retrieves tessellation control shader body.
   13280  *
   13281  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   13282  *                                     the shader, false to skip it.
   13283  *
   13284  *  @return Requested string.
   13285  **/
   13286 std::string NegativeTest8::getTessellationControlShaderBody(bool include_invalid_declaration) const
   13287 {
   13288 	std::stringstream result_sstream;
   13289 
   13290 	result_sstream << "#version 400\n"
   13291 					  "\n"
   13292 					  "#extension GL_ARB_shader_subroutine : require\n"
   13293 					  "\n"
   13294 					  "layout (vertices = 4) out;\n"
   13295 					  "\n";
   13296 
   13297 	if (include_invalid_declaration)
   13298 	{
   13299 		result_sstream << "subroutine void subroutineTestTypeTC(out vec4 test);\n"
   13300 						  "\n"
   13301 						  "subroutine(subroutineTestTypeTC) void test_impl1(out vec4 test);\n"
   13302 						  "\n"
   13303 						  "subroutine uniform subroutineTestTypeTC test_subroutineTC;\n";
   13304 	};
   13305 
   13306 	result_sstream << "\n"
   13307 					  "void main()\n"
   13308 					  "{\n";
   13309 
   13310 	if (include_invalid_declaration)
   13311 	{
   13312 		result_sstream << "    test_subroutineTC(gl_out[gl_InvocationID].gl_Position);\n";
   13313 	}
   13314 	else
   13315 	{
   13316 		result_sstream << "    gl_out[gl_InvocationID].gl_Position = vec4(0, 1, 2, 3);\n";
   13317 	}
   13318 
   13319 	result_sstream << "}\n";
   13320 
   13321 	return result_sstream.str();
   13322 }
   13323 
   13324 /** Retrieves tessellation evaluation body.
   13325  *
   13326  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   13327  *                                     the shader, false to skip it.
   13328  *
   13329  *  @return Requested string.
   13330  **/
   13331 std::string NegativeTest8::getTessellationEvaluationShaderBody(bool include_invalid_declaration) const
   13332 {
   13333 	std::stringstream result_sstream;
   13334 
   13335 	result_sstream << "#version 400\n"
   13336 					  "\n"
   13337 					  "#extension GL_ARB_shader_subroutine : require\n"
   13338 					  "\n"
   13339 					  "layout (quads) in;\n"
   13340 					  "\n";
   13341 
   13342 	if (include_invalid_declaration)
   13343 	{
   13344 		result_sstream << "subroutine void subroutineTestTypeTE(out vec4 test);\n"
   13345 						  "\n"
   13346 						  "subroutine(subroutineTestTypeTE) void test_impl1(out vec4 test);\n"
   13347 						  "\n"
   13348 						  "subroutine uniform subroutineTestTypeTE test_subroutineTE;\n";
   13349 	};
   13350 
   13351 	result_sstream << "\n"
   13352 					  "void main()\n"
   13353 					  "{\n";
   13354 
   13355 	if (include_invalid_declaration)
   13356 	{
   13357 		result_sstream << "    test_subroutineTE(gl_Position);\n";
   13358 	}
   13359 	else
   13360 	{
   13361 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   13362 	}
   13363 
   13364 	result_sstream << "}\n";
   13365 
   13366 	return result_sstream.str();
   13367 }
   13368 
   13369 /** Retrieves vertex shader body.
   13370  *
   13371  *  @param include_invalid_declaration true if a subroutine prototype should be included in
   13372  *                                     the shader, false to skip it.
   13373  *
   13374  *  @return Requested string.
   13375  **/
   13376 std::string NegativeTest8::getVertexShaderBody(bool include_invalid_declaration) const
   13377 {
   13378 	std::stringstream result_sstream;
   13379 
   13380 	result_sstream << "#version 400\n"
   13381 					  "\n"
   13382 					  "#extension GL_ARB_shader_subroutine : require\n"
   13383 					  "\n";
   13384 
   13385 	if (include_invalid_declaration)
   13386 	{
   13387 		result_sstream << "subroutine void subroutineTestTypeVS(out vec4 test);\n"
   13388 						  "\n"
   13389 						  "subroutine(subroutineTestTypeVS) void test_impl1(out vec4 test);\n"
   13390 						  "\n"
   13391 						  "subroutine uniform subroutineTestTypeVS test_subroutineVS;\n";
   13392 	};
   13393 
   13394 	result_sstream << "\n"
   13395 					  "void main()\n"
   13396 					  "{\n";
   13397 
   13398 	if (include_invalid_declaration)
   13399 	{
   13400 		result_sstream << "    test_subroutineVS(gl_Position);\n";
   13401 	}
   13402 	else
   13403 	{
   13404 		result_sstream << "    gl_Position = vec4(0, 1, 2, 3);\n";
   13405 	}
   13406 
   13407 	result_sstream << "}\n";
   13408 
   13409 	return result_sstream.str();
   13410 }
   13411 
   13412 /** Executes test iteration.
   13413  *
   13414  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   13415  */
   13416 tcu::TestNode::IterateResult NegativeTest8::iterate()
   13417 {
   13418 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   13419 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   13420 	{
   13421 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   13422 	}
   13423 
   13424 	/* Iterate over all shader stages. For each iteration, iteration-specific shader stage
   13425 	 * will feature an invalid subroutine definition. Other shader stages will be assigned
   13426 	 * valid bodies. The test fails if a program built of such shaders links successfully.
   13427 	 */
   13428 	for (int shader_stage = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   13429 		 shader_stage < static_cast<int>(Utils::SHADER_STAGE_COUNT); ++shader_stage)
   13430 	{
   13431 		executeIteration(static_cast<Utils::_shader_stage>(shader_stage));
   13432 		deinitIteration();
   13433 	} /* for (all shader stages) */
   13434 
   13435 	/* All done */
   13436 	if (m_has_test_passed)
   13437 	{
   13438 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   13439 	}
   13440 	else
   13441 	{
   13442 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   13443 	}
   13444 
   13445 	return STOP;
   13446 }
   13447 
   13448 /** Constructor.
   13449  *
   13450  *  @param context Rendering context.
   13451  **/
   13452 NegativeTest9::NegativeTest9(deqp::Context& context)
   13453 	: TestCase(context, "subroutines_cannot_be_assigned_float_int_values_or_be_compared",
   13454 			   "Make sure it is not possible to assign float/int to subroutine "
   13455 			   "uniform and that subroutine uniform values cannot be compared.")
   13456 	, m_has_test_passed(true)
   13457 	, m_po_id(0)
   13458 	, m_vs_id(0)
   13459 {
   13460 	/* Left blank intentionally */
   13461 }
   13462 
   13463 /** Deinitializes any GL objects that may have been created during
   13464  *  test execution.
   13465  **/
   13466 void NegativeTest9::deinit()
   13467 {
   13468 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13469 
   13470 	if (m_po_id != 0)
   13471 	{
   13472 		gl.deleteProgram(m_po_id);
   13473 
   13474 		m_po_id = 0;
   13475 	}
   13476 
   13477 	if (m_vs_id != 0)
   13478 	{
   13479 		gl.deleteShader(m_vs_id);
   13480 
   13481 		m_vs_id = 0;
   13482 	}
   13483 }
   13484 
   13485 /** Returns a literal corresponding to user-specified test case enum.
   13486  *
   13487  *  @param test_case As per description.
   13488  *
   13489  *  @return Requested string.
   13490  **/
   13491 std::string NegativeTest9::getTestCaseString(const _test_case& test_case)
   13492 {
   13493 	std::string result = "?";
   13494 
   13495 	switch (test_case)
   13496 	{
   13497 	case TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   13498 		result = "TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT";
   13499 		break;
   13500 	case TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   13501 		result = "TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT";
   13502 		break;
   13503 	case TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON:
   13504 		result = "TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON";
   13505 		break;
   13506 	default:
   13507 		break;
   13508 	}
   13509 
   13510 	return result;
   13511 }
   13512 
   13513 /** Retrieves vertex shader body for user-specified test case.
   13514  *
   13515  *  @param test_case As per description.
   13516  *
   13517  *  @return Requested string.
   13518  **/
   13519 std::string NegativeTest9::getVertexShader(const _test_case& test_case)
   13520 {
   13521 	std::stringstream result_sstream;
   13522 
   13523 	/* Form pre-amble */
   13524 	result_sstream << "#version 400\n"
   13525 					  "\n"
   13526 					  "#extension GL_ARB_shader_subroutine : require\n"
   13527 					  "\n"
   13528 					  /* Define a subroutine */
   13529 					  "subroutine void subroutineType(inout vec4 test);\n"
   13530 					  "\n"
   13531 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13532 					  "{\n"
   13533 					  "    test += vec4(0, 1, 2, 3);\n"
   13534 					  "}\n"
   13535 					  "\n"
   13536 					  "subroutine uniform subroutineType function;\n"
   13537 					  "\n";
   13538 
   13539 	/* Include case-specific implementation */
   13540 	switch (test_case)
   13541 	{
   13542 	case TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   13543 	{
   13544 		result_sstream << "void main()\n"
   13545 						  "{\n"
   13546 						  "    function = 1.0f;\n"
   13547 						  "\n"
   13548 						  "    function(gl_Position);\n"
   13549 						  "}\n";
   13550 
   13551 		break;
   13552 	}
   13553 
   13554 	case TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT:
   13555 	{
   13556 		result_sstream << "void main()\n"
   13557 						  "{\n"
   13558 						  "    function = 1;\n"
   13559 						  "\n"
   13560 						  "    function(gl_Position);\n"
   13561 						  "}\n";
   13562 
   13563 		break;
   13564 	}
   13565 
   13566 	case TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON:
   13567 	{
   13568 		result_sstream << "subroutine uniform subroutineType function2;\n"
   13569 						  "\n"
   13570 						  "void main()\n"
   13571 						  "{\n"
   13572 						  "    if (function == function2)\n"
   13573 						  "    {\n"
   13574 						  "        function(gl_Position);\n"
   13575 						  "    }\n"
   13576 						  "    else\n"
   13577 						  "    {\n"
   13578 						  "        function2(gl_Position);\n"
   13579 						  "    }\n"
   13580 						  "}\n";
   13581 
   13582 		break;
   13583 	}
   13584 
   13585 	default:
   13586 		break;
   13587 	} /* switch (test_case) */
   13588 
   13589 	/* Done */
   13590 	return result_sstream.str();
   13591 }
   13592 
   13593 /** Executes test iteration.
   13594  *
   13595  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   13596  */
   13597 tcu::TestNode::IterateResult NegativeTest9::iterate()
   13598 {
   13599 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13600 
   13601 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   13602 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   13603 	{
   13604 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   13605 	}
   13606 
   13607 	/* Iterate over all test cases */
   13608 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   13609 	{
   13610 		/* Try to build a program object using invalid vertex shader, specific to the
   13611 		 * iteration we're currently in */
   13612 		std::string vs_body = getVertexShader(static_cast<_test_case>(test_case));
   13613 
   13614 		if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "",   /* tc_body */
   13615 												  "",				 /* te_body */
   13616 												  "",				 /* gs_body */
   13617 												  "",				 /* fs_body */
   13618 												  DE_NULL,			 /* xfb_varyings */
   13619 												  0,				 /* n_xfb_varyings */
   13620 												  &m_vs_id, DE_NULL, /* out_tc_id */
   13621 												  DE_NULL,			 /* out_te_id */
   13622 												  DE_NULL,			 /* out_gs_id */
   13623 												  DE_NULL,			 /* out_fs_id */
   13624 												  &m_po_id))
   13625 		{
   13626 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   13627 							   << getTestCaseString(static_cast<_test_case>(test_case))
   13628 							   << "] test case, even though it was invalid." << tcu::TestLog::EndMessage;
   13629 
   13630 			m_has_test_passed = false;
   13631 		}
   13632 
   13633 		/* Delete any objects that may have been created */
   13634 		deinit();
   13635 	} /* for (all test cases) */
   13636 
   13637 	/** All done */
   13638 	if (m_has_test_passed)
   13639 	{
   13640 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   13641 	}
   13642 	else
   13643 	{
   13644 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   13645 	}
   13646 
   13647 	return STOP;
   13648 }
   13649 
   13650 /** Constructor.
   13651  *
   13652  *  @param context Rendering context.
   13653  **/
   13654 NegativeTest10::NegativeTest10(deqp::Context& context)
   13655 	: TestCase(context, "function_overloading_forbidden_for_subroutines",
   13656 			   "Check that an overloaded function cannot be declared with subroutine and "
   13657 			   "a program will fail to compile or link if any shader or stage contains"
   13658 			   " two or more  functions with the same name if the name is associated with"
   13659 			   " a subroutine type.")
   13660 	, m_has_test_passed(true)
   13661 	, m_fs_id(0)
   13662 	, m_gs_id(0)
   13663 	, m_po_id(0)
   13664 	, m_tc_id(0)
   13665 	, m_te_id(0)
   13666 	, m_vs_id(0)
   13667 {
   13668 	/* Left blank intentionally */
   13669 }
   13670 
   13671 /** Deinitializes any GL objects that may have been created during
   13672  *  test execution.
   13673  **/
   13674 void NegativeTest10::deinit()
   13675 {
   13676 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13677 
   13678 	if (m_fs_id != 0)
   13679 	{
   13680 		gl.deleteShader(m_fs_id);
   13681 
   13682 		m_fs_id = 0;
   13683 	}
   13684 
   13685 	if (m_gs_id != 0)
   13686 	{
   13687 		gl.deleteShader(m_gs_id);
   13688 
   13689 		m_gs_id = 0;
   13690 	}
   13691 
   13692 	if (m_po_id != 0)
   13693 	{
   13694 		gl.deleteProgram(m_po_id);
   13695 
   13696 		m_po_id = 0;
   13697 	}
   13698 
   13699 	if (m_tc_id != 0)
   13700 	{
   13701 		gl.deleteShader(m_tc_id);
   13702 
   13703 		m_tc_id = 0;
   13704 	}
   13705 
   13706 	if (m_te_id != 0)
   13707 	{
   13708 		gl.deleteShader(m_te_id);
   13709 
   13710 		m_te_id = 0;
   13711 	}
   13712 
   13713 	if (m_vs_id != 0)
   13714 	{
   13715 		gl.deleteShader(m_vs_id);
   13716 
   13717 		m_vs_id = 0;
   13718 	}
   13719 }
   13720 
   13721 /** Retrieves fragment shader that should be used for the purpose of the test.
   13722  *  An overloaded version of a subroutine function is inserted if
   13723  *  @param include_duplicate_function flag is set to true.
   13724  *
   13725  *  @param include_duplicate_function As per description.
   13726  *
   13727  *  @return Requested string.
   13728  **/
   13729 std::string NegativeTest10::getFragmentShader(bool include_duplicate_function)
   13730 {
   13731 	std::stringstream result_sstream;
   13732 
   13733 	result_sstream << "#version 400\n"
   13734 					  "\n"
   13735 					  "#extension GL_ARB_shader_subroutine : require\n"
   13736 					  "\n"
   13737 					  "subroutine void subroutineType(inout vec4 test);\n"
   13738 					  "\n"
   13739 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13740 					  "{\n"
   13741 					  "    test = vec4(2, 3, 4, 5);\n"
   13742 					  "}\n"
   13743 					  "\n"
   13744 					  "subroutine uniform subroutineType function;\n"
   13745 					  "out vec4 result;\n"
   13746 					  "\n";
   13747 
   13748 	if (include_duplicate_function)
   13749 	{
   13750 		result_sstream << "void test_function(inout vec4 test)\n"
   13751 						  "{\n"
   13752 						  "    test = vec4(3, 4, 5, 6);\n"
   13753 						  "}\n"
   13754 						  "\n";
   13755 	}
   13756 
   13757 	result_sstream << "void main()\n"
   13758 					  "{\n"
   13759 					  "    test_function(result);\n"
   13760 					  "}\n";
   13761 
   13762 	return result_sstream.str();
   13763 }
   13764 
   13765 /** Retrieves geometry shader that should be used for the purpose of the test.
   13766  *  An overloaded version of a subroutine function is inserted if
   13767  *  @param include_duplicate_function flag is set to true.
   13768  *
   13769  *  @param include_duplicate_function As per description.
   13770  *
   13771  *  @return Requested string.
   13772  **/
   13773 std::string NegativeTest10::getGeometryShader(bool include_duplicate_function)
   13774 {
   13775 	std::stringstream result_sstream;
   13776 
   13777 	result_sstream << "#version 400\n"
   13778 					  "\n"
   13779 					  "#extension GL_ARB_shader_subroutine : require\n"
   13780 					  "\n"
   13781 					  "layout (triangles)                        in;\n"
   13782 					  "layout (triangle_strip, max_vertices = 4) out;\n"
   13783 					  "\n"
   13784 					  "subroutine void subroutineType(inout vec4 test);\n"
   13785 					  "\n"
   13786 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13787 					  "{\n"
   13788 					  "    test = vec4(2, 3, 4, 5);\n"
   13789 					  "}\n"
   13790 					  "\n"
   13791 					  "subroutine uniform subroutineType function;\n"
   13792 					  "\n";
   13793 
   13794 	if (include_duplicate_function)
   13795 	{
   13796 		result_sstream << "void test_function(inout vec4 test)\n"
   13797 						  "{\n"
   13798 						  "    test = vec4(3, 4, 5, 6);\n"
   13799 						  "}\n"
   13800 						  "\n";
   13801 	}
   13802 
   13803 	result_sstream << "void main()\n"
   13804 					  "{\n"
   13805 					  "    function(gl_Position);\n"
   13806 					  "    EmitVertex();\n"
   13807 					  "    EndPrimitive();\n"
   13808 					  "}\n";
   13809 
   13810 	return result_sstream.str();
   13811 }
   13812 
   13813 /** Retrieves tess control shader that should be used for the purpose of the test.
   13814  *  An overloaded version of a subroutine function is inserted if
   13815  *  @param include_duplicate_function flag is set to true.
   13816  *
   13817  *  @param include_duplicate_function As per description.
   13818  *
   13819  *  @return Requested string.
   13820  **/
   13821 std::string NegativeTest10::getTessellationControlShader(bool include_duplicate_function)
   13822 {
   13823 	std::stringstream result_sstream;
   13824 
   13825 	result_sstream << "#version 400\n"
   13826 					  "\n"
   13827 					  "#extension GL_ARB_shader_subroutine : require\n"
   13828 					  "\n"
   13829 					  "layout (vertices = 4) out;\n"
   13830 					  "\n"
   13831 					  "subroutine void subroutineType(inout vec4 test);\n"
   13832 					  "\n"
   13833 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13834 					  "{\n"
   13835 					  "    test = vec4(2, 3, 4, 5);\n"
   13836 					  "}\n"
   13837 					  "\n"
   13838 					  "subroutine uniform subroutineType function;\n"
   13839 					  "\n";
   13840 
   13841 	if (include_duplicate_function)
   13842 	{
   13843 		result_sstream << "void test_function(inout vec4 test)\n"
   13844 						  "{\n"
   13845 						  "    test = vec4(3, 4, 5, 6);\n"
   13846 						  "}\n"
   13847 						  "\n";
   13848 	}
   13849 
   13850 	result_sstream << "void main()\n"
   13851 					  "{\n"
   13852 					  "    vec4 temp;\n"
   13853 					  "\n"
   13854 					  "    function(temp);\n"
   13855 					  "\n"
   13856 					  "    gl_out[gl_InvocationID].gl_Position = temp;\n"
   13857 					  "    gl_TessLevelInner[0]                = temp.x;\n"
   13858 					  "    gl_TessLevelInner[1]                = temp.y;\n"
   13859 					  "    gl_TessLevelOuter[0]                = temp.z;\n"
   13860 					  "    gl_TessLevelOuter[1]                = temp.w;\n"
   13861 					  "    gl_TessLevelOuter[2]                = temp.x;\n"
   13862 					  "    gl_TessLevelOuter[3]                = temp.y;\n"
   13863 					  "}\n";
   13864 
   13865 	return result_sstream.str();
   13866 }
   13867 
   13868 /** Retrieves tess evaluation shader that should be used for the purpose of the test.
   13869  *  An overloaded version of a subroutine function is inserted if
   13870  *  @param include_duplicate_function flag is set to true.
   13871  *
   13872  *  @param include_duplicate_function As per description.
   13873  *
   13874  *  @return Requested string.
   13875  **/
   13876 std::string NegativeTest10::getTessellationEvaluationShader(bool include_duplicate_function)
   13877 {
   13878 	std::stringstream result_sstream;
   13879 
   13880 	result_sstream << "#version 400\n"
   13881 					  "\n"
   13882 					  "#extension GL_ARB_shader_subroutine : require\n"
   13883 					  "\n"
   13884 					  "layout (quads) in;\n"
   13885 					  "\n"
   13886 					  "subroutine void subroutineType(inout vec4 test);\n"
   13887 					  "\n"
   13888 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13889 					  "{\n"
   13890 					  "    test = vec4(2, 3, 4, 5);\n"
   13891 					  "}\n"
   13892 					  "\n"
   13893 					  "subroutine uniform subroutineType function;\n"
   13894 					  "\n";
   13895 
   13896 	if (include_duplicate_function)
   13897 	{
   13898 		result_sstream << "void test_function(inout vec4 test)\n"
   13899 						  "{\n"
   13900 						  "    test = vec4(3, 4, 5, 6);\n"
   13901 						  "}\n"
   13902 						  "\n";
   13903 	}
   13904 
   13905 	result_sstream << "void main()\n"
   13906 					  "{\n"
   13907 					  "    vec4 temp;\n"
   13908 					  "\n"
   13909 					  "    function(temp);\n"
   13910 					  "\n"
   13911 					  "    gl_Position = temp;\n"
   13912 					  "}\n";
   13913 
   13914 	return result_sstream.str();
   13915 }
   13916 
   13917 /** Retrieves vertex shader that should be used for the purpose of the test.
   13918  *  An overloaded version of a subroutine function is inserted if
   13919  *  @param include_duplicate_function flag is set to true.
   13920  *
   13921  *  @param include_duplicate_function As per description.
   13922  *
   13923  *  @return Requested string.
   13924  **/
   13925 std::string NegativeTest10::getVertexShader(bool include_duplicate_function)
   13926 {
   13927 	std::stringstream result_sstream;
   13928 
   13929 	result_sstream << "#version 400\n"
   13930 					  "\n"
   13931 					  "#extension GL_ARB_shader_subroutine : require\n"
   13932 					  "\n"
   13933 					  "subroutine void subroutineType(inout vec4 test);\n"
   13934 					  "\n"
   13935 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   13936 					  "{\n"
   13937 					  "    test = vec4(2, 3, 4, 5);\n"
   13938 					  "}\n"
   13939 					  "\n"
   13940 					  "subroutine uniform subroutineType function;\n"
   13941 					  "\n";
   13942 
   13943 	if (include_duplicate_function)
   13944 	{
   13945 		result_sstream << "void test_function(inout vec4 test)\n"
   13946 						  "{\n"
   13947 						  "    test = vec4(3, 4, 5, 6);\n"
   13948 						  "}\n"
   13949 						  "\n";
   13950 	}
   13951 
   13952 	result_sstream << "void main()\n"
   13953 					  "{\n"
   13954 					  "    function(gl_Position);\n"
   13955 					  "}\n";
   13956 
   13957 	return result_sstream.str();
   13958 }
   13959 
   13960 /** Fills m_test_cases field with test case descriptors */
   13961 void NegativeTest10::initTestCases()
   13962 {
   13963 	/* For each test case, only one shader stage should define a function that
   13964 	 * has already been defined as a subroutine. */
   13965 	for (int offending_shader_stage_it = static_cast<int>(Utils::SHADER_STAGE_FIRST);
   13966 		 offending_shader_stage_it != static_cast<int>(Utils::SHADER_STAGE_COUNT); ++offending_shader_stage_it)
   13967 	{
   13968 		Utils::_shader_stage offending_shader_stage = static_cast<Utils::_shader_stage>(offending_shader_stage_it);
   13969 		/* Form the test case descriptor */
   13970 		std::stringstream name_sstream;
   13971 		_test_case		  test_case;
   13972 
   13973 		name_sstream << "Broken shader stage:" << Utils::getShaderStageString(offending_shader_stage);
   13974 
   13975 		test_case.fs_body = getFragmentShader(offending_shader_stage == Utils::SHADER_STAGE_FRAGMENT);
   13976 		test_case.gs_body = getGeometryShader(offending_shader_stage == Utils::SHADER_STAGE_GEOMETRY);
   13977 		test_case.name	= name_sstream.str();
   13978 		test_case.tc_body =
   13979 			getTessellationControlShader(offending_shader_stage == Utils::SHADER_STAGE_TESSELLATION_CONTROL);
   13980 		test_case.te_body =
   13981 			getTessellationEvaluationShader(offending_shader_stage == Utils::SHADER_STAGE_TESSELLATION_EVALUATION);
   13982 		test_case.vs_body = getVertexShader(offending_shader_stage == Utils::SHADER_STAGE_VERTEX);
   13983 
   13984 		m_test_cases.push_back(test_case);
   13985 	}
   13986 }
   13987 
   13988 /** Executes test iteration.
   13989  *
   13990  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   13991  */
   13992 tcu::TestNode::IterateResult NegativeTest10::iterate()
   13993 {
   13994 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   13995 
   13996 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   13997 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   13998 	{
   13999 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   14000 	}
   14001 
   14002 	/* Form test cases */
   14003 	initTestCases();
   14004 
   14005 	/* Iterate over all test cases */
   14006 	for (_test_cases_const_iterator test_case_iterator = m_test_cases.begin(); test_case_iterator != m_test_cases.end();
   14007 		 ++test_case_iterator)
   14008 	{
   14009 		const _test_case& test_case = *test_case_iterator;
   14010 
   14011 		/* Try to build the program object */
   14012 		if (ShaderSubroutine::Utils::buildProgram(gl, test_case.vs_body, test_case.tc_body, test_case.te_body,
   14013 												  test_case.gs_body, test_case.fs_body, DE_NULL, /* xfb_varyings */
   14014 												  0,											 /* n_xfb_varyings */
   14015 												  &m_vs_id, (test_case.tc_body.length() > 0) ? &m_tc_id : DE_NULL,
   14016 												  (test_case.te_body.length() > 0) ? &m_te_id : DE_NULL,
   14017 												  (test_case.gs_body.length() > 0) ? &m_gs_id : DE_NULL,
   14018 												  (test_case.fs_body.length() > 0) ? &m_fs_id : DE_NULL, &m_po_id))
   14019 		{
   14020 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   14021 							   << test_case.name << "] test case, even though it was invalid."
   14022 							   << tcu::TestLog::EndMessage;
   14023 
   14024 			m_has_test_passed = false;
   14025 		}
   14026 
   14027 		/* Delete any objects that may have been created */
   14028 		deinit();
   14029 	} /* for (all test cases) */
   14030 
   14031 	/** All done */
   14032 	if (m_has_test_passed)
   14033 	{
   14034 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   14035 	}
   14036 	else
   14037 	{
   14038 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   14039 	}
   14040 
   14041 	return STOP;
   14042 }
   14043 
   14044 /** Constructor.
   14045  *
   14046  *  @param context Rendering context.
   14047  **/
   14048 NegativeTest11::NegativeTest11(deqp::Context& context)
   14049 	: TestCase(context, "subroutine_uniforms_used_for_sampling_atomic_image_functions",
   14050 			   "Tries to use subroutine uniforms in invalid way in sampling, "
   14051 			   "atomic and image functions. Verifies that compile- or link-time "
   14052 			   "error occurs.")
   14053 	, m_has_test_passed(true)
   14054 	, m_po_id(0)
   14055 	, m_vs_id(0)
   14056 {
   14057 	/* Left blank intentionally */
   14058 }
   14059 
   14060 /** Deinitializes any GL objects that may have been created during
   14061  *  test execution.
   14062  **/
   14063 void NegativeTest11::deinit()
   14064 {
   14065 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   14066 
   14067 	if (m_po_id != 0)
   14068 	{
   14069 		gl.deleteProgram(m_po_id);
   14070 
   14071 		m_po_id = 0;
   14072 	}
   14073 
   14074 	if (m_vs_id != 0)
   14075 	{
   14076 		gl.deleteShader(m_vs_id);
   14077 
   14078 		m_vs_id = 0;
   14079 	}
   14080 }
   14081 
   14082 /** Returns a literal corresponding to user-specified test case enum.
   14083  *
   14084  *  @param test_case As per description.
   14085  *
   14086  *  @return Requested string.
   14087  **/
   14088 std::string NegativeTest11::getTestCaseString(const _test_case& test_case)
   14089 {
   14090 	std::string result = "?";
   14091 
   14092 	switch (test_case)
   14093 	{
   14094 	case TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT:
   14095 		result = "TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT";
   14096 		break;
   14097 	case TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT:
   14098 		result = "TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT";
   14099 		break;
   14100 	case TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT:
   14101 		result = "TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT";
   14102 		break;
   14103 	default:
   14104 		break;
   14105 	}
   14106 
   14107 	return result;
   14108 }
   14109 
   14110 /** Retrieves vertex shader body for user-specified test case.
   14111  *
   14112  *  @param test_case As per description.
   14113  *
   14114  *  @return Requested string.
   14115  **/
   14116 std::string NegativeTest11::getVertexShader(const _test_case& test_case)
   14117 {
   14118 	std::stringstream result_sstream;
   14119 
   14120 	/* Form pre-amble */
   14121 	result_sstream << "#version 400\n"
   14122 					  "\n"
   14123 					  "#extension GL_ARB_shader_subroutine : require\n";
   14124 
   14125 	if (test_case == TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT)
   14126 	{
   14127 		result_sstream << "#extension GL_ARB_shader_atomic_counters : require\n";
   14128 	}
   14129 
   14130 	result_sstream << "\n"
   14131 					  /* Define a subroutine */
   14132 					  "subroutine void subroutineType(inout vec4 test);\n"
   14133 					  "\n"
   14134 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   14135 					  "{\n"
   14136 					  "    test += vec4(0, 1, 2, 3);\n"
   14137 					  "}\n"
   14138 					  "\n"
   14139 					  "subroutine uniform subroutineType function;\n"
   14140 					  "\n"
   14141 
   14142 					  /* Define main() body */
   14143 					  "void main()\n"
   14144 					  "{\n";
   14145 
   14146 	/* Implement case-specific behavior */
   14147 	switch (test_case)
   14148 	{
   14149 	case TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT:
   14150 	{
   14151 		result_sstream << "if (atomicCounter(function) > 2)\n"
   14152 						  "{\n"
   14153 						  "    gl_Position = vec4(1);\n"
   14154 						  "}\n";
   14155 
   14156 		break;
   14157 	}
   14158 
   14159 	case TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT:
   14160 	{
   14161 		result_sstream << "imageStore(function, vec2(0.0, 1.0), vec4(1.0) );\n";
   14162 
   14163 		break;
   14164 	}
   14165 
   14166 	case TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT:
   14167 	{
   14168 		result_sstream << "gl_Position = texture(function, vec2(1.0) );\n";
   14169 
   14170 		break;
   14171 	}
   14172 
   14173 	default:
   14174 		break;
   14175 	} /* switch (test_case) */
   14176 
   14177 	/* Close main() body */
   14178 	result_sstream << "}\n";
   14179 
   14180 	/* Done */
   14181 	return result_sstream.str();
   14182 }
   14183 
   14184 /** Executes test iteration.
   14185  *
   14186  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   14187  */
   14188 tcu::TestNode::IterateResult NegativeTest11::iterate()
   14189 {
   14190 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   14191 
   14192 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   14193 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   14194 	{
   14195 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   14196 	}
   14197 
   14198 	/* Iterate over all test cases */
   14199 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   14200 	{
   14201 		if (static_cast<_test_case>(test_case) == TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT &&
   14202 			!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_atomic_counters"))
   14203 		{
   14204 			/* This iteration requires atomic counter support that this GL implementation
   14205 			 * is not capable of. Skip the iteration
   14206 			 */
   14207 			continue;
   14208 		}
   14209 
   14210 		/* Try to build a program object using invalid vertex shader, specific to the
   14211 		 * iteration we're currently in */
   14212 		std::string vs_body = getVertexShader(static_cast<_test_case>(test_case));
   14213 
   14214 		if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "",   /* tc_body */
   14215 												  "",				 /* te_body */
   14216 												  "",				 /* gs_body */
   14217 												  "",				 /* fs_body */
   14218 												  DE_NULL,			 /* xfb_varyings */
   14219 												  0,				 /* n_xfb_varyings */
   14220 												  &m_vs_id, DE_NULL, /* out_tc_id */
   14221 												  DE_NULL,			 /* out_te_id */
   14222 												  DE_NULL,			 /* out_gs_id */
   14223 												  DE_NULL,			 /* out_fs_id */
   14224 												  &m_po_id))
   14225 		{
   14226 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   14227 							   << getTestCaseString(static_cast<_test_case>(test_case))
   14228 							   << "] test case, even though it was invalid." << tcu::TestLog::EndMessage;
   14229 
   14230 			m_has_test_passed = false;
   14231 		}
   14232 
   14233 		/* Delete any objects that may have been created */
   14234 		deinit();
   14235 	} /* for (all test cases) */
   14236 
   14237 	/** All done */
   14238 	if (m_has_test_passed)
   14239 	{
   14240 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   14241 	}
   14242 	else
   14243 	{
   14244 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   14245 	}
   14246 
   14247 	return STOP;
   14248 }
   14249 
   14250 /** Constructor.
   14251  *
   14252  *  @param context Rendering context.
   14253  **/
   14254 NegativeTest12::NegativeTest12(deqp::Context& context)
   14255 	: TestCase(context, "subroutines_not_allowed_as_variables_constructors_and_argument_or_return_types",
   14256 			   "Verifies that it is not allowed to use subroutine type for "
   14257 			   "local/global variables, constructors or argument/return type.")
   14258 	, m_has_test_passed(true)
   14259 	, m_po_id(0)
   14260 	, m_vs_id(0)
   14261 {
   14262 	/* Left blank intentionally */
   14263 }
   14264 
   14265 /** Deinitializes any GL objects that may have been created during
   14266  *  test execution.
   14267  **/
   14268 void NegativeTest12::deinit()
   14269 {
   14270 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   14271 
   14272 	if (m_po_id != 0)
   14273 	{
   14274 		gl.deleteProgram(m_po_id);
   14275 
   14276 		m_po_id = 0;
   14277 	}
   14278 
   14279 	if (m_vs_id != 0)
   14280 	{
   14281 		gl.deleteShader(m_vs_id);
   14282 
   14283 		m_vs_id = 0;
   14284 	}
   14285 }
   14286 
   14287 /** Returns a literal corresponding to user-specified test case enum.
   14288  *
   14289  *  @param test_case As per description.
   14290  *
   14291  *  @return Requested string.
   14292  **/
   14293 std::string NegativeTest12::getTestCaseString(const _test_case& test_case)
   14294 {
   14295 	std::string result = "?";
   14296 
   14297 	switch (test_case)
   14298 	{
   14299 	case TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE:
   14300 		result = "TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE";
   14301 		break;
   14302 	case TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE:
   14303 		result = "TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE";
   14304 		break;
   14305 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR:
   14306 		result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR";
   14307 		break;
   14308 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT:
   14309 		result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT";
   14310 		break;
   14311 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE:
   14312 		result = "TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE";
   14313 		break;
   14314 	default:
   14315 		break;
   14316 	}
   14317 
   14318 	return result;
   14319 }
   14320 
   14321 /** Retrieves vertex shader body for user-specified test case.
   14322  *
   14323  *  @param test_case As per description.
   14324  *
   14325  *  @return Requested string.
   14326  **/
   14327 std::string NegativeTest12::getVertexShader(const _test_case& test_case)
   14328 {
   14329 	std::stringstream result_sstream;
   14330 
   14331 	/* Form pre-amble */
   14332 	result_sstream << "#version 400\n"
   14333 					  "\n"
   14334 					  "#extension GL_ARB_shader_subroutine : require\n"
   14335 					  "\n"
   14336 					  /* Define a subroutine */
   14337 					  "subroutine void subroutineType(inout vec4 test);\n"
   14338 					  "\n"
   14339 					  "subroutine(subroutineType) void test_function(inout vec4 test)\n"
   14340 					  "{\n"
   14341 					  "    test += vec4(0, 1, 2, 3);\n"
   14342 					  "}\n"
   14343 					  "\n"
   14344 					  "subroutine uniform subroutineType function;\n"
   14345 					  "\n";
   14346 
   14347 	/* Include case-specific implementation */
   14348 	switch (test_case)
   14349 	{
   14350 	case TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE:
   14351 	{
   14352 		result_sstream << "void main()\n"
   14353 						  "{\n"
   14354 						  "    subroutine subroutineType function2;\n"
   14355 						  "    vec4                      result;\n"
   14356 						  "\n"
   14357 						  "    function2(result);\n"
   14358 						  "    gl_Position = result;\n"
   14359 						  "}\n";
   14360 
   14361 		break;
   14362 	}
   14363 
   14364 	case TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE:
   14365 	{
   14366 		result_sstream << "subroutine subroutineType function2;\n"
   14367 						  "\n"
   14368 						  "void main()\n"
   14369 						  "{\n"
   14370 						  "    vec4 result;\n"
   14371 						  "\n"
   14372 						  "    function2(result);\n"
   14373 						  "    gl_Position = result;\n"
   14374 						  "}\n";
   14375 
   14376 		break;
   14377 	}
   14378 
   14379 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR:
   14380 	{
   14381 		result_sstream << "void main()\n"
   14382 						  "{\n"
   14383 						  "    subroutineType(function);\n"
   14384 						  "}\n";
   14385 
   14386 		break;
   14387 	}
   14388 
   14389 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT:
   14390 	{
   14391 		result_sstream << "vec4 test_function(subroutineType argument)\n"
   14392 						  "{\n"
   14393 						  "    vec4 result = vec4(1, 2, 3, 4);\n"
   14394 						  "\n"
   14395 						  "    argument(result);\n"
   14396 						  "\n"
   14397 						  "    return result;\n"
   14398 						  "}\n"
   14399 						  "\n"
   14400 						  "void main()\n"
   14401 						  "{\n"
   14402 						  "    test_function(function);\n"
   14403 						  "}\n";
   14404 
   14405 		break;
   14406 	}
   14407 
   14408 	case TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE:
   14409 	{
   14410 		result_sstream << "subroutineType test_function()\n"
   14411 						  "{\n"
   14412 						  "    return function;\n"
   14413 						  "}\n"
   14414 						  "\n"
   14415 						  "void main()\n"
   14416 						  "{\n"
   14417 						  "    test_function()(gl_Position);\n"
   14418 						  "}\n";
   14419 
   14420 		break;
   14421 	}
   14422 
   14423 	default:
   14424 		break;
   14425 	} /* switch (test_case) */
   14426 
   14427 	/* Done */
   14428 	return result_sstream.str();
   14429 }
   14430 
   14431 /** Executes test iteration.
   14432  *
   14433  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   14434  */
   14435 tcu::TestNode::IterateResult NegativeTest12::iterate()
   14436 {
   14437 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   14438 
   14439 	/* Do not execute the test if GL_ARB_shader_subroutine is not supported */
   14440 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_subroutine"))
   14441 	{
   14442 		throw tcu::NotSupportedError("GL_ARB_shader_subroutine is not supported.");
   14443 	}
   14444 
   14445 	/* Iterate over all test cases */
   14446 	for (int test_case = static_cast<int>(TEST_CASE_FIRST); test_case != static_cast<int>(TEST_CASE_COUNT); ++test_case)
   14447 	{
   14448 		/* Try to build a program object using invalid vertex shader, specific to the
   14449 		 * iteration we're currently in */
   14450 		std::string vs_body = getVertexShader(static_cast<_test_case>(test_case));
   14451 
   14452 		if (ShaderSubroutine::Utils::buildProgram(gl, vs_body, "",   /* tc_body */
   14453 												  "",				 /* te_body */
   14454 												  "",				 /* gs_body */
   14455 												  "",				 /* fs_body */
   14456 												  DE_NULL,			 /* xfb_varyings */
   14457 												  0,				 /* n_xfb_varyings */
   14458 												  &m_vs_id, DE_NULL, /* out_tc_id */
   14459 												  DE_NULL,			 /* out_te_id */
   14460 												  DE_NULL,			 /* out_gs_id */
   14461 												  DE_NULL,			 /* out_fs_id */
   14462 												  &m_po_id))
   14463 		{
   14464 			m_testCtx.getLog() << tcu::TestLog::Message << "A program object was successfully built for ["
   14465 							   << getTestCaseString(static_cast<_test_case>(test_case))
   14466 							   << "] test case, even though it was invalid." << tcu::TestLog::EndMessage;
   14467 
   14468 			m_has_test_passed = false;
   14469 		}
   14470 
   14471 		/* Delete any objects that may have been created */
   14472 		deinit();
   14473 	} /* for (all test cases) */
   14474 
   14475 	/** All done */
   14476 	if (m_has_test_passed)
   14477 	{
   14478 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   14479 	}
   14480 	else
   14481 	{
   14482 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   14483 	}
   14484 
   14485 	return STOP;
   14486 }
   14487 
   14488 } /* ShaderSubroutine */
   14489 
   14490 /** Constructor.
   14491  *
   14492  *  @param context Rendering context.
   14493  **/
   14494 ShaderSubroutineTests::ShaderSubroutineTests(deqp::Context& context)
   14495 	: TestCaseGroup(context, "shader_subroutine", "Verifies \"shader_subroutine\" functionality")
   14496 {
   14497 	/* Left blank on purpose */
   14498 }
   14499 
   14500 /** Initializes a texture_storage_multisample test group.
   14501  *
   14502  **/
   14503 void ShaderSubroutineTests::init(void)
   14504 {
   14505 	addChild(new ShaderSubroutine::APITest1(m_context));
   14506 	addChild(new ShaderSubroutine::APITest2(m_context));
   14507 	addChild(new ShaderSubroutine::FunctionalTest1_2(m_context));
   14508 	addChild(new ShaderSubroutine::FunctionalTest3_4(m_context));
   14509 	addChild(new ShaderSubroutine::FunctionalTest5(m_context));
   14510 	addChild(new ShaderSubroutine::FunctionalTest6(m_context));
   14511 	addChild(new ShaderSubroutine::FunctionalTest7_8(m_context));
   14512 	addChild(new ShaderSubroutine::FunctionalTest9(m_context));
   14513 	addChild(new ShaderSubroutine::FunctionalTest10(m_context));
   14514 	addChild(new ShaderSubroutine::FunctionalTest11(m_context));
   14515 	addChild(new ShaderSubroutine::FunctionalTest12(m_context));
   14516 	addChild(new ShaderSubroutine::FunctionalTest13(m_context));
   14517 	addChild(new ShaderSubroutine::FunctionalTest14_15(m_context));
   14518 	addChild(new ShaderSubroutine::FunctionalTest16(m_context));
   14519 	addChild(new ShaderSubroutine::FunctionalTest17(m_context));
   14520 	addChild(new ShaderSubroutine::FunctionalTest18_19(m_context));
   14521 	addChild(new ShaderSubroutine::FunctionalTest20_21(m_context));
   14522 	addChild(new ShaderSubroutine::NegativeTest1(m_context));
   14523 	addChild(new ShaderSubroutine::NegativeTest2(m_context));
   14524 	addChild(new ShaderSubroutine::NegativeTest3(m_context));
   14525 	addChild(new ShaderSubroutine::NegativeTest4(m_context));
   14526 	addChild(new ShaderSubroutine::NegativeTest5(m_context));
   14527 	addChild(new ShaderSubroutine::NegativeTest6(m_context));
   14528 	addChild(new ShaderSubroutine::NegativeTest7(m_context));
   14529 	addChild(new ShaderSubroutine::NegativeTest8(m_context));
   14530 	addChild(new ShaderSubroutine::NegativeTest9(m_context));
   14531 	addChild(new ShaderSubroutine::NegativeTest10(m_context));
   14532 	addChild(new ShaderSubroutine::NegativeTest11(m_context));
   14533 	addChild(new ShaderSubroutine::NegativeTest12(m_context));
   14534 }
   14535 
   14536 } /* glcts namespace */
   14537