/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 * \file  gl4GPUShaderFP64Tests.cpp
 * \brief Implements conformance tests for "GPU Shader FP64" functionality.
 */ /*-------------------------------------------------------------------*/

#include "gl4cGPUShaderFP64Tests.hpp"
#include "gluContextInfo.hpp"
#include "glwFunctions.hpp"
#include "tcuMatrix.hpp"
#include "tcuTestLog.hpp"

#include <iomanip>

#include "deMath.h"
#include "deUniquePtr.hpp"
#include "tcuMatrixUtil.hpp"
#include "tcuVectorUtil.hpp"

#include <cstdlib>
#include <cstring>
#include <limits>
#include <memory>

namespace gl4cts
{

const glw::GLenum Utils::programInfo::ARB_COMPUTE_SHADER = 0x91B9;

/** Constructor
 *
 * @param context Test context
 **/
Utils::programInfo::programInfo(deqp::Context& context)
	: m_context(context)
	, m_compute_shader_id(0)
	, m_fragment_shader_id(0)
	, m_geometry_shader_id(0)
	, m_program_object_id(0)
	, m_tesselation_control_shader_id(0)
	, m_tesselation_evaluation_shader_id(0)
	, m_vertex_shader_id(0)
{
	/* Nothing to be done here */
}

/** Destructor
 *
 **/
Utils::programInfo::~programInfo()
{
	/* GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Make sure program object is no longer used by GL */
	gl.useProgram(0);

	/* Clean program object */
	if (0 != m_program_object_id)
	{
		gl.deleteProgram(m_program_object_id);
		m_program_object_id = 0;
	}

	/* Clean shaders */
	if (0 != m_compute_shader_id)
	{
		gl.deleteShader(m_compute_shader_id);
		m_compute_shader_id = 0;
	}

	if (0 != m_fragment_shader_id)
	{
		gl.deleteShader(m_fragment_shader_id);
		m_fragment_shader_id = 0;
	}

	if (0 != m_geometry_shader_id)
	{
		gl.deleteShader(m_geometry_shader_id);
		m_geometry_shader_id = 0;
	}

	if (0 != m_tesselation_control_shader_id)
	{
		gl.deleteShader(m_tesselation_control_shader_id);
		m_tesselation_control_shader_id = 0;
	}

	if (0 != m_tesselation_evaluation_shader_id)
	{
		gl.deleteShader(m_tesselation_evaluation_shader_id);
		m_tesselation_evaluation_shader_id = 0;
	}

	if (0 != m_vertex_shader_id)
	{
		gl.deleteShader(m_vertex_shader_id);
		m_vertex_shader_id = 0;
	}
}

/** Build program
 *
 * @param compute_shader_code                Compute shader source code
 * @param fragment_shader_code               Fragment shader source code
 * @param geometry_shader_code               Geometry shader source code
 * @param tesselation_control_shader_code    Tesselation control shader source code
 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
 * @param vertex_shader_code                 Vertex shader source code
 * @param varying_names                      Array of strings containing names of varyings to be captured with transfrom feedback
 * @param n_varying_names                    Number of varyings to be captured with transfrom feedback
 **/
void Utils::programInfo::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
							   const glw::GLchar* geometry_shader_code,
							   const glw::GLchar* tesselation_control_shader_code,
							   const glw::GLchar* tesselation_evaluation_shader_code,
							   const glw::GLchar* vertex_shader_code, const glw::GLchar* const* varying_names,
							   glw::GLuint n_varying_names)
{
	/* GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create shader objects and compile */
	if (0 != compute_shader_code)
	{
		m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

		compile(m_compute_shader_id, compute_shader_code);
	}

	if (0 != fragment_shader_code)
	{
		m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

		compile(m_fragment_shader_id, fragment_shader_code);
	}

	if (0 != geometry_shader_code)
	{
		m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

		compile(m_geometry_shader_id, geometry_shader_code);
	}

	if (0 != tesselation_control_shader_code)
	{
		m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

		compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
	}

	if (0 != tesselation_evaluation_shader_code)
	{
		m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

		compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
	}

	if (0 != vertex_shader_code)
	{
		m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

		compile(m_vertex_shader_id, vertex_shader_code);
	}

	/* Create program object */
	m_program_object_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");

	/* Set up captyured varyings' names */
	if (0 != n_varying_names)
	{
		gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
	}

	/* Link program */
	link();
}

/** Compile shader
 *
 * @param shader_id   Shader object id
 * @param shader_code Shader source code
 **/
void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
{
	/* GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Compilation status */
	glw::GLint status = GL_FALSE;

	/* Set source code */
	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");

	/* Compile */
	gl.compileShader(shader_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");

	/* Get compilation status */
	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");

	/* Log compilation error */
	if (GL_TRUE != status)
	{
		glw::GLint				 length = 0;
		std::vector<glw::GLchar> message;

		/* Error log length */
		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");

		/* Prepare storage */
		message.resize(length);

		/* Get error log */
		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");

		/* Log */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
											<< &message[0] << "\nShader source\n"
											<< shader_code << tcu::TestLog::EndMessage;

		TCU_FAIL("Failed to compile shader");
	}
}

/** Attach shaders and link program
 *
 **/
void Utils::programInfo::link() const
{
	/* GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Link status */
	glw::GLint status = GL_FALSE;

	/* Attach shaders */
	if (0 != m_compute_shader_id)
	{
		gl.attachShader(m_program_object_id, m_compute_shader_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
	}

	if (0 != m_fragment_shader_id)
	{
		gl.attachShader(m_program_object_id, m_fragment_shader_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
	}

	if (0 != m_geometry_shader_id)
	{
		gl.attachShader(m_program_object_id, m_geometry_shader_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
	}

	if (0 != m_tesselation_control_shader_id)
	{
		gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
	}

	if (0 != m_tesselation_evaluation_shader_id)
	{
		gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
	}

	if (0 != m_vertex_shader_id)
	{
		gl.attachShader(m_program_object_id, m_vertex_shader_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
	}

	/* Link */
	gl.linkProgram(m_program_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");

	/* Get link status */
	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");

	/* Log link error */
	if (GL_TRUE != status)
	{
		glw::GLint				 length = 0;
		std::vector<glw::GLchar> message;

		/* Get error log length */
		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");

		message.resize(length);

		/* Get error log */
		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");

		/* Log */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
											<< &message[0] << tcu::TestLog::EndMessage;

		TCU_FAIL("Failed to link program");
	}
}

/** Retrieves base type of user-provided variable type. (eg. VARIABLE_TYPE_DOUBLE for double-precision
 *  matrix types.
 *
 *  @param type Variable type to return base type for.
 *
 *  @return Requested value or VARAIBLE_TYPE_UNKNOWN if @param type was not recognized.
 **/
Utils::_variable_type Utils::getBaseVariableType(_variable_type type)
{
	_variable_type result = VARIABLE_TYPE_UNKNOWN;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
	{
		result = VARIABLE_TYPE_BOOL;

		break;
	}

	case VARIABLE_TYPE_DOUBLE:
	case VARIABLE_TYPE_DMAT2:
	case VARIABLE_TYPE_DMAT2X3:
	case VARIABLE_TYPE_DMAT2X4:
	case VARIABLE_TYPE_DMAT3:
	case VARIABLE_TYPE_DMAT3X2:
	case VARIABLE_TYPE_DMAT3X4:
	case VARIABLE_TYPE_DMAT4:
	case VARIABLE_TYPE_DMAT4X2:
	case VARIABLE_TYPE_DMAT4X3:
	case VARIABLE_TYPE_DVEC2:
	case VARIABLE_TYPE_DVEC3:
	case VARIABLE_TYPE_DVEC4:
	{
		result = VARIABLE_TYPE_DOUBLE;

		break;
	}

	case VARIABLE_TYPE_INT:
	case VARIABLE_TYPE_IVEC2:
	case VARIABLE_TYPE_IVEC3:
	case VARIABLE_TYPE_IVEC4:
	{
		result = VARIABLE_TYPE_INT;

		break;
	}

	case VARIABLE_TYPE_UINT:
	case VARIABLE_TYPE_UVEC2:
	case VARIABLE_TYPE_UVEC3:
	case VARIABLE_TYPE_UVEC4:
	{
		result = VARIABLE_TYPE_UINT;

		break;
	}

	case VARIABLE_TYPE_FLOAT:
	case VARIABLE_TYPE_MAT2:
	case VARIABLE_TYPE_MAT2X3:
	case VARIABLE_TYPE_MAT2X4:
	case VARIABLE_TYPE_MAT3:
	case VARIABLE_TYPE_MAT3X2:
	case VARIABLE_TYPE_MAT3X4:
	case VARIABLE_TYPE_MAT4:
	case VARIABLE_TYPE_MAT4X2:
	case VARIABLE_TYPE_MAT4X3:
	case VARIABLE_TYPE_VEC2:
	case VARIABLE_TYPE_VEC3:
	case VARIABLE_TYPE_VEC4:
	{
		result = VARIABLE_TYPE_FLOAT;

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized variable type");
	}
	} /* switch (type) */

	return result;
}

/** Returns size (in bytes) of a single component of a base variable type.
 *
 *  @param type Base variable type to use for the query.
 *
 *  @return Requested value or 0 if @param type was not recognized.
 **/
unsigned int Utils::getBaseVariableTypeComponentSize(_variable_type type)
{
	unsigned int result = 0;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
		result = sizeof(bool);
		break;
	case VARIABLE_TYPE_DOUBLE:
		result = sizeof(double);
		break;
	case VARIABLE_TYPE_FLOAT:
		result = sizeof(float);
		break;
	case VARIABLE_TYPE_INT:
		result = sizeof(int);
		break;
	case VARIABLE_TYPE_UINT:
		result = sizeof(unsigned int);
		break;

	default:
	{
		TCU_FAIL("Unrecognized variable type");
	}
	} /* switch (type) */

	return result;
}

/** Returns component, corresponding to user-specified index
 *  (eg. index:0 corresponds to 'x', index:1 corresponds to 'y',
 *  and so on.
 *
 *  @param index Component index.
 *
 *  @return As per description.
 **/
unsigned char Utils::getComponentAtIndex(unsigned int index)
{
	unsigned char result = '?';

	switch (index)
	{
	case 0:
		result = 'x';
		break;
	case 1:
		result = 'y';
		break;
	case 2:
		result = 'z';
		break;
	case 3:
		result = 'w';
		break;

	default:
	{
		TCU_FAIL("Unrecognized component index");
	}
	}

	return result;
}

/** Get _variable_type representing double-precision type with given dimmensions
 *
 * @param n_columns Number of columns
 * @param n_row     Number of rows
 *
 * @return Corresponding _variable_type
 **/
Utils::_variable_type Utils::getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
{
	Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;

	static const _variable_type types[4][4] = {
		{ VARIABLE_TYPE_DOUBLE, VARIABLE_TYPE_DVEC2, VARIABLE_TYPE_DVEC3, VARIABLE_TYPE_DVEC4 },
		{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT2, VARIABLE_TYPE_DMAT2X3, VARIABLE_TYPE_DMAT2X4 },
		{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT3X2, VARIABLE_TYPE_DMAT3, VARIABLE_TYPE_DMAT3X4 },
		{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT4X2, VARIABLE_TYPE_DMAT4X3, VARIABLE_TYPE_DMAT4 }
	};

	type = types[n_columns - 1][n_rows - 1];

	return type;
}

/** Returns a single-precision equivalent of a double-precision floating-point variable
 *  type.
 *
 *  @param type Double-precision variable type. Only VARIABLE_TYPE_D* variable types
 *              are accepted.
 *
 *  @return Requested GLSL type.
 **/
std::string Utils::getFPVariableTypeStringForVariableType(_variable_type type)
{
	std::string result = "[?]";

	switch (type)
	{
	case VARIABLE_TYPE_DOUBLE:
		result = "float";
		break;
	case VARIABLE_TYPE_DMAT2:
		result = "mat2";
		break;
	case VARIABLE_TYPE_DMAT2X3:
		result = "mat2x3";
		break;
	case VARIABLE_TYPE_DMAT2X4:
		result = "mat2x4";
		break;
	case VARIABLE_TYPE_DMAT3:
		result = "mat3";
		break;
	case VARIABLE_TYPE_DMAT3X2:
		result = "mat3x2";
		break;
	case VARIABLE_TYPE_DMAT3X4:
		result = "mat3x4";
		break;
	case VARIABLE_TYPE_DMAT4:
		result = "mat4";
		break;
	case VARIABLE_TYPE_DMAT4X2:
		result = "mat4x2";
		break;
	case VARIABLE_TYPE_DMAT4X3:
		result = "mat4x3";
		break;
	case VARIABLE_TYPE_DVEC2:
		result = "vec2";
		break;
	case VARIABLE_TYPE_DVEC3:
		result = "vec3";
		break;
	case VARIABLE_TYPE_DVEC4:
		result = "vec4";
		break;

	default:
	{
		TCU_FAIL("Unrecognized variable type");
	}
	}; /* switch (type) */

	return result;
}

/** Returns GL data type enum corresponding to user-provided base variable type.
 *
 *  @param type Base variable type to return corresponding GLenum value for.
 *
 *  @return Corresponding GLenum value or GL_NONE if the input value was not
 *          recognized.
 **/
glw::GLenum Utils::getGLDataTypeOfBaseVariableType(_variable_type type)
{
	glw::GLenum result = GL_NONE;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
		result = GL_BOOL;
		break;
	case VARIABLE_TYPE_DOUBLE:
		result = GL_DOUBLE;
		break;
	case VARIABLE_TYPE_FLOAT:
		result = GL_FLOAT;
		break;
	case VARIABLE_TYPE_INT:
		result = GL_INT;
		break;
	case VARIABLE_TYPE_UINT:
		result = GL_UNSIGNED_INT;
		break;

	default:
	{
		TCU_FAIL("Unrecognized variable type");
	}
	}

	return result;
}

/** Return GLenum representing given <type>
 *
 * @param type Type of variable
 *
 * @return GL enumeration
 **/
glw::GLenum Utils::getGLDataTypeOfVariableType(_variable_type type)
{
	glw::GLenum result = GL_NONE;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
		result = GL_BOOL;
		break;
	case VARIABLE_TYPE_DOUBLE:
		result = GL_DOUBLE;
		break;
	case VARIABLE_TYPE_DMAT2:
		result = GL_DOUBLE_MAT2;
		break;
	case VARIABLE_TYPE_DMAT2X3:
		result = GL_DOUBLE_MAT2x3;
		break;
	case VARIABLE_TYPE_DMAT2X4:
		result = GL_DOUBLE_MAT2x4;
		break;
	case VARIABLE_TYPE_DMAT3:
		result = GL_DOUBLE_MAT3;
		break;
	case VARIABLE_TYPE_DMAT3X2:
		result = GL_DOUBLE_MAT3x2;
		break;
	case VARIABLE_TYPE_DMAT3X4:
		result = GL_DOUBLE_MAT3x4;
		break;
	case VARIABLE_TYPE_DMAT4:
		result = GL_DOUBLE_MAT4;
		break;
	case VARIABLE_TYPE_DMAT4X2:
		result = GL_DOUBLE_MAT4x2;
		break;
	case VARIABLE_TYPE_DMAT4X3:
		result = GL_DOUBLE_MAT4x3;
		break;
	case VARIABLE_TYPE_DVEC2:
		result = GL_DOUBLE_VEC2;
		break;
	case VARIABLE_TYPE_DVEC3:
		result = GL_DOUBLE_VEC3;
		break;
	case VARIABLE_TYPE_DVEC4:
		result = GL_DOUBLE_VEC4;
		break;
	case VARIABLE_TYPE_FLOAT:
		result = GL_FLOAT;
		break;
	case VARIABLE_TYPE_INT:
		result = GL_INT;
		break;
	case VARIABLE_TYPE_IVEC2:
		result = GL_INT_VEC2;
		break;
	case VARIABLE_TYPE_IVEC3:
		result = GL_INT_VEC3;
		break;
	case VARIABLE_TYPE_IVEC4:
		result = GL_INT_VEC4;
		break;
	case VARIABLE_TYPE_MAT2:
		result = GL_FLOAT_MAT2;
		break;
	case VARIABLE_TYPE_MAT2X3:
		result = GL_FLOAT_MAT2x3;
		break;
	case VARIABLE_TYPE_MAT2X4:
		result = GL_FLOAT_MAT2x4;
		break;
	case VARIABLE_TYPE_MAT3:
		result = GL_FLOAT_MAT3;
		break;
	case VARIABLE_TYPE_MAT3X2:
		result = GL_FLOAT_MAT3x2;
		break;
	case VARIABLE_TYPE_MAT3X4:
		result = GL_FLOAT_MAT3x4;
		break;
	case VARIABLE_TYPE_MAT4:
		result = GL_FLOAT_MAT4;
		break;
	case VARIABLE_TYPE_MAT4X2:
		result = GL_FLOAT_MAT4x2;
		break;
	case VARIABLE_TYPE_MAT4X3:
		result = GL_FLOAT_MAT4x3;
		break;
	case VARIABLE_TYPE_UINT:
		result = GL_UNSIGNED_INT;
		break;
	case VARIABLE_TYPE_UVEC2:
		result = GL_UNSIGNED_INT_VEC2;
		break;
	case VARIABLE_TYPE_UVEC3:
		result = GL_UNSIGNED_INT_VEC3;
		break;
	case VARIABLE_TYPE_UVEC4:
		result = GL_UNSIGNED_INT_VEC4;
		break;
	case VARIABLE_TYPE_VEC2:
		result = GL_FLOAT_VEC2;
		break;
	case VARIABLE_TYPE_VEC3:
		result = GL_FLOAT_VEC3;
		break;
	case VARIABLE_TYPE_VEC4:
		result = GL_FLOAT_VEC4;
		break;

	default:
	{
		TCU_FAIL("Unrecognized variable type");
	}
	}

	return result;
}

/** Get _variable_type representing integer type with given dimmensions
 *
 * @param n_columns Number of columns
 * @param n_row     Number of rows
 *
 * @return Corresponding _variable_type
 **/
Utils::_variable_type Utils::getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
{
	Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;

	static const _variable_type types[4] = { VARIABLE_TYPE_INT, VARIABLE_TYPE_IVEC2, VARIABLE_TYPE_IVEC3,
											 VARIABLE_TYPE_IVEC4 };

	if (1 != n_columns)
	{
		TCU_FAIL("Not implemented");
	}
	else
	{
		type = types[n_rows - 1];
	}

	return type;
}

/** Returns te number of components that variables defined with user-specified type
 *  support. For matrix types, total amount of values accessible for the type will be
 *  returned.
 *
 *  @param type Variable type to return the described vale for.
 *
 *  @return As per description or 0 if @param type was not recognized.
 */
unsigned int Utils::getNumberOfComponentsForVariableType(_variable_type type)
{
	unsigned int result = 0;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
	case VARIABLE_TYPE_DOUBLE:
	case VARIABLE_TYPE_FLOAT:
	case VARIABLE_TYPE_INT:
	case VARIABLE_TYPE_UINT:
	{
		result = 1;

		break;
	}

	case VARIABLE_TYPE_DVEC2:
	case VARIABLE_TYPE_IVEC2:
	case VARIABLE_TYPE_UVEC2:
	case VARIABLE_TYPE_VEC2:
	{
		result = 2;

		break;
	}

	case VARIABLE_TYPE_DVEC3:
	case VARIABLE_TYPE_IVEC3:
	case VARIABLE_TYPE_UVEC3:
	case VARIABLE_TYPE_VEC3:
	{
		result = 3;

		break;
	}

	case VARIABLE_TYPE_DVEC4:
	case VARIABLE_TYPE_IVEC4:
	case VARIABLE_TYPE_UVEC4:
	case VARIABLE_TYPE_VEC4:
	{
		result = 4;

		break;
	}

	case VARIABLE_TYPE_DMAT2:
	case VARIABLE_TYPE_MAT2:
	{
		result = 2 * 2;

		break;
	}

	case VARIABLE_TYPE_DMAT2X3:
	case VARIABLE_TYPE_DMAT3X2:
	case VARIABLE_TYPE_MAT2X3:
	case VARIABLE_TYPE_MAT3X2:
	{
		result = 2 * 3;

		break;
	}

	case VARIABLE_TYPE_DMAT2X4:
	case VARIABLE_TYPE_DMAT4X2:
	case VARIABLE_TYPE_MAT2X4:
	case VARIABLE_TYPE_MAT4X2:
	{
		result = 2 * 4;

		break;
	}

	case VARIABLE_TYPE_DMAT3:
	case VARIABLE_TYPE_MAT3:
	{
		result = 3 * 3;

		break;
	}

	case VARIABLE_TYPE_DMAT3X4:
	case VARIABLE_TYPE_DMAT4X3:
	case VARIABLE_TYPE_MAT3X4:
	case VARIABLE_TYPE_MAT4X3:
	{
		result = 3 * 4;

		break;
	}

	case VARIABLE_TYPE_DMAT4:
	case VARIABLE_TYPE_MAT4:
	{
		result = 4 * 4;

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized type");
	}
	} /* switch (type) */

	return result;
}

/** Returns number of columns user-specified matrix variable type describes.
 *
 *  @param type Variable type to use for the query. Only VARIABLE_TYPE_DMAT*
 *              values are valid.
 *
 *  @return As per description.
 **/
unsigned int Utils::getNumberOfColumnsForVariableType(_variable_type type)
{
	unsigned int result = 0;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
	case VARIABLE_TYPE_DOUBLE:
	case VARIABLE_TYPE_FLOAT:
	case VARIABLE_TYPE_INT:
	case VARIABLE_TYPE_UINT:
	case VARIABLE_TYPE_DVEC2:
	case VARIABLE_TYPE_IVEC2:
	case VARIABLE_TYPE_UVEC2:
	case VARIABLE_TYPE_VEC2:
	case VARIABLE_TYPE_DVEC3:
	case VARIABLE_TYPE_IVEC3:
	case VARIABLE_TYPE_UVEC3:
	case VARIABLE_TYPE_VEC3:
	case VARIABLE_TYPE_DVEC4:
	case VARIABLE_TYPE_IVEC4:
	case VARIABLE_TYPE_UVEC4:
	case VARIABLE_TYPE_VEC4:
	{
		result = 1;

		break;
	}

	case VARIABLE_TYPE_DMAT2:
	case VARIABLE_TYPE_DMAT2X3:
	case VARIABLE_TYPE_DMAT2X4:
	case VARIABLE_TYPE_MAT2:
	case VARIABLE_TYPE_MAT2X3:
	case VARIABLE_TYPE_MAT2X4:
	{
		result = 2;

		break;
	}

	case VARIABLE_TYPE_DMAT3:
	case VARIABLE_TYPE_DMAT3X2:
	case VARIABLE_TYPE_DMAT3X4:
	case VARIABLE_TYPE_MAT3:
	case VARIABLE_TYPE_MAT3X2:
	case VARIABLE_TYPE_MAT3X4:
	{
		result = 3;

		break;
	}

	case VARIABLE_TYPE_DMAT4:
	case VARIABLE_TYPE_DMAT4X2:
	case VARIABLE_TYPE_DMAT4X3:
	case VARIABLE_TYPE_MAT4:
	case VARIABLE_TYPE_MAT4X2:
	case VARIABLE_TYPE_MAT4X3:
	{
		result = 4;

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized type");
	}
	} /* switch (type) */

	return result;
}

/** Returns maximum number of uniform locations taken by user-specified double-precision
 *  variable type.
 *
 *  @param type Variable type to use for the query. Only VARIABLE_TYPE_D* values are valid.
 *
 *  @return As per description.
 **/
unsigned int Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type)
{
	unsigned int result = 0;

	switch (type)
	{
	case VARIABLE_TYPE_DOUBLE:
		result = 1;
		break;
	case VARIABLE_TYPE_DVEC2:
		result = 1;
		break;
	case VARIABLE_TYPE_DVEC3:
		result = 2;
		break;
	case VARIABLE_TYPE_DVEC4:
		result = 2;
		break;
	case VARIABLE_TYPE_DMAT2:
		result = 2;
		break;
	case VARIABLE_TYPE_DMAT2X3:
		result = 6;
		break;
	case VARIABLE_TYPE_DMAT2X4:
		result = 8;
		break;
	case VARIABLE_TYPE_DMAT3:
		result = 6;
		break;
	case VARIABLE_TYPE_DMAT3X2:
		result = 4;
		break;
	case VARIABLE_TYPE_DMAT3X4:
		result = 8;
		break;
	case VARIABLE_TYPE_DMAT4:
		result = 8;
		break;
	case VARIABLE_TYPE_DMAT4X2:
		result = 4;
		break;
	case VARIABLE_TYPE_DMAT4X3:
		result = 6;
		break;

	default:
	{
		TCU_FAIL("Unrecognized type");
	}
	} /* switch (type) */

	return result;
}

/** Get number of rows for given variable type
 *
 * @param type Type of variable
 *
 * @return Number of rows
 **/
unsigned int Utils::getNumberOfRowsForVariableType(_variable_type type)
{
	unsigned int result = 0;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
	case VARIABLE_TYPE_DOUBLE:
	case VARIABLE_TYPE_FLOAT:
	case VARIABLE_TYPE_INT:
	case VARIABLE_TYPE_UINT:
	{
		result = 1;

		break;
	}

	case VARIABLE_TYPE_DVEC2:
	case VARIABLE_TYPE_IVEC2:
	case VARIABLE_TYPE_UVEC2:
	case VARIABLE_TYPE_VEC2:
	case VARIABLE_TYPE_DMAT2:
	case VARIABLE_TYPE_DMAT3X2:
	case VARIABLE_TYPE_DMAT4X2:
	case VARIABLE_TYPE_MAT2:
	case VARIABLE_TYPE_MAT3X2:
	case VARIABLE_TYPE_MAT4X2:
	{
		result = 2;

		break;
	}

	case VARIABLE_TYPE_DVEC3:
	case VARIABLE_TYPE_IVEC3:
	case VARIABLE_TYPE_UVEC3:
	case VARIABLE_TYPE_VEC3:
	case VARIABLE_TYPE_DMAT2X3:
	case VARIABLE_TYPE_DMAT3:
	case VARIABLE_TYPE_DMAT4X3:
	case VARIABLE_TYPE_MAT2X3:
	case VARIABLE_TYPE_MAT3:
	case VARIABLE_TYPE_MAT4X3:
	{
		result = 3;

		break;
	}

	case VARIABLE_TYPE_DVEC4:
	case VARIABLE_TYPE_IVEC4:
	case VARIABLE_TYPE_UVEC4:
	case VARIABLE_TYPE_VEC4:
	case VARIABLE_TYPE_DMAT2X4:
	case VARIABLE_TYPE_DMAT3X4:
	case VARIABLE_TYPE_DMAT4:
	case VARIABLE_TYPE_MAT2X4:
	case VARIABLE_TYPE_MAT3X4:
	case VARIABLE_TYPE_MAT4:
	{
		result = 4;

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized type");
	}
	} /* switch (type) */

	return result;
}

/** Returns variable type of a matrix constructed by multiplying two matrices.
 *
 *  @param type_matrix_a L-side matrix type.
 *  @param type_matrix_b R-side matrix type.
 *
 *  @return As per description.
 **/
Utils::_variable_type Utils::getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a,
																	 _variable_type type_matrix_b)
{
	const unsigned int	n_a_columns	  = Utils::getNumberOfColumnsForVariableType(type_matrix_a);
	const unsigned int	n_a_components   = Utils::getNumberOfComponentsForVariableType(type_matrix_a);
	const unsigned int	n_a_rows		   = n_a_components / n_a_columns;
	const unsigned int	n_b_columns	  = Utils::getNumberOfColumnsForVariableType(type_matrix_b);
	const unsigned int	n_result_columns = n_b_columns;
	const unsigned int	n_result_rows	= n_a_rows;
	Utils::_variable_type result;

	switch (n_result_columns)
	{
	case 2:
	{
		switch (n_result_rows)
		{
		case 2:
			result = VARIABLE_TYPE_DMAT2;
			break;
		case 3:
			result = VARIABLE_TYPE_DMAT2X3;
			break;
		case 4:
			result = VARIABLE_TYPE_DMAT2X4;
			break;

		default:
		{
			TCU_FAIL("Unrecognized amount of rows in result variable");
		}
		} /* switch (n_result_rows) */

		break;
	} /* case 2: */

	case 3:
	{
		switch (n_result_rows)
		{
		case 2:
			result = VARIABLE_TYPE_DMAT3X2;
			break;
		case 3:
			result = VARIABLE_TYPE_DMAT3;
			break;
		case 4:
			result = VARIABLE_TYPE_DMAT3X4;
			break;

		default:
		{
			TCU_FAIL("Unrecognized amount of rows in result variable");
		}
		} /* switch (n_result_rows) */

		break;
	} /* case 3: */

	case 4:
	{
		switch (n_result_rows)
		{
		case 2:
			result = VARIABLE_TYPE_DMAT4X2;
			break;
		case 3:
			result = VARIABLE_TYPE_DMAT4X3;
			break;
		case 4:
			result = VARIABLE_TYPE_DMAT4;
			break;

		default:
		{
			TCU_FAIL("Unrecognized amount of rows in result variable");
		}
		} /* switch (n_result_rows) */

		break;
	} /* case 4: */

	default:
	{
		TCU_FAIL("Unrecognized amount of columns in result variable");
	}
	} /* switch (n_result_columns) */

	/* Done */
	return result;
}

/** Returns a string holding the value represented by user-provided variable, for which
 *  the data are represented in @param type variable type.
 *
 *  @return As per description.
 **/
std::string Utils::getStringForVariableTypeValue(_variable_type type, const unsigned char* data_ptr)
{
	std::stringstream result_sstream;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
		result_sstream << *((bool*)data_ptr);
		break;
	case VARIABLE_TYPE_DOUBLE:
		result_sstream << *((double*)data_ptr);
		break;
	case VARIABLE_TYPE_FLOAT:
		result_sstream << *((float*)data_ptr);
		break;
	case VARIABLE_TYPE_INT:
		result_sstream << *((int*)data_ptr);
		break;
	case VARIABLE_TYPE_UINT:
		result_sstream << *((unsigned int*)data_ptr);
		break;

	default:
	{
		TCU_FAIL("Unrecognized variable type requested");
	}
	} /* switch (type) */

	return result_sstream.str();
}

/** Returns variable type of a transposed matrix of user-specified variable type.
 *
 *  @param type Variable type of the matrix to be transposed.
 *
 *  @return Transposed matrix variable type.
 **/
Utils::_variable_type Utils::getTransposedMatrixVariableType(Utils::_variable_type type)
{
	Utils::_variable_type result;

	switch (type)
	{
	case VARIABLE_TYPE_DMAT2:
		result = VARIABLE_TYPE_DMAT2;
		break;
	case VARIABLE_TYPE_DMAT2X3:
		result = VARIABLE_TYPE_DMAT3X2;
		break;
	case VARIABLE_TYPE_DMAT2X4:
		result = VARIABLE_TYPE_DMAT4X2;
		break;
	case VARIABLE_TYPE_DMAT3:
		result = VARIABLE_TYPE_DMAT3;
		break;
	case VARIABLE_TYPE_DMAT3X2:
		result = VARIABLE_TYPE_DMAT2X3;
		break;
	case VARIABLE_TYPE_DMAT3X4:
		result = VARIABLE_TYPE_DMAT4X3;
		break;
	case VARIABLE_TYPE_DMAT4:
		result = VARIABLE_TYPE_DMAT4;
		break;
	case VARIABLE_TYPE_DMAT4X2:
		result = VARIABLE_TYPE_DMAT2X4;
		break;
	case VARIABLE_TYPE_DMAT4X3:
		result = VARIABLE_TYPE_DMAT3X4;
		break;

	default:
	{
		TCU_FAIL("Unrecognized double-precision matrix variable type.");
	}
	} /* switch (type) */

	return result;
}

/** Get _variable_type representing unsigned integer type with given dimmensions
 *
 * @param n_columns Number of columns
 * @param n_row     Number of rows
 *
 * @return Corresponding _variable_type
 **/
Utils::_variable_type Utils::getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
{
	Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;

	static const _variable_type types[4] = { VARIABLE_TYPE_UINT, VARIABLE_TYPE_UVEC2, VARIABLE_TYPE_UVEC3,
											 VARIABLE_TYPE_UVEC4 };

	if (1 != n_columns)
	{
		TCU_FAIL("Not implemented");
	}
	else
	{
		type = types[n_rows - 1];
	}

	return type;
}

/** Returns a literal corresponding to a GLSL keyword describing user-specified
 *  variable type.
 *
 *  @param type Variable type to use for the query.
 *
 *  @return Requested GLSL keyword or [?] if @param type was not recognized.
 **/
std::string Utils::getVariableTypeString(_variable_type type)
{
	std::string result = "[?]";

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
		result = "bool";
		break;
	case VARIABLE_TYPE_BVEC2:
		result = "bvec2";
		break;
	case VARIABLE_TYPE_BVEC3:
		result = "bvec3";
		break;
	case VARIABLE_TYPE_BVEC4:
		result = "bvec4";
		break;
	case VARIABLE_TYPE_DOUBLE:
		result = "double";
		break;
	case VARIABLE_TYPE_DMAT2:
		result = "dmat2";
		break;
	case VARIABLE_TYPE_DMAT2X3:
		result = "dmat2x3";
		break;
	case VARIABLE_TYPE_DMAT2X4:
		result = "dmat2x4";
		break;
	case VARIABLE_TYPE_DMAT3:
		result = "dmat3";
		break;
	case VARIABLE_TYPE_DMAT3X2:
		result = "dmat3x2";
		break;
	case VARIABLE_TYPE_DMAT3X4:
		result = "dmat3x4";
		break;
	case VARIABLE_TYPE_DMAT4:
		result = "dmat4";
		break;
	case VARIABLE_TYPE_DMAT4X2:
		result = "dmat4x2";
		break;
	case VARIABLE_TYPE_DMAT4X3:
		result = "dmat4x3";
		break;
	case VARIABLE_TYPE_DVEC2:
		result = "dvec2";
		break;
	case VARIABLE_TYPE_DVEC3:
		result = "dvec3";
		break;
	case VARIABLE_TYPE_DVEC4:
		result = "dvec4";
		break;
	case VARIABLE_TYPE_FLOAT:
		result = "float";
		break;
	case VARIABLE_TYPE_INT:
		result = "int";
		break;
	case VARIABLE_TYPE_IVEC2:
		result = "ivec2";
		break;
	case VARIABLE_TYPE_IVEC3:
		result = "ivec3";
		break;
	case VARIABLE_TYPE_IVEC4:
		result = "ivec4";
		break;
	case VARIABLE_TYPE_MAT2:
		result = "mat2";
		break;
	case VARIABLE_TYPE_MAT2X3:
		result = "mat2x3";
		break;
	case VARIABLE_TYPE_MAT2X4:
		result = "mat2x4";
		break;
	case VARIABLE_TYPE_MAT3:
		result = "mat3";
		break;
	case VARIABLE_TYPE_MAT3X2:
		result = "mat3x2";
		break;
	case VARIABLE_TYPE_MAT3X4:
		result = "mat3x4";
		break;
	case VARIABLE_TYPE_MAT4:
		result = "mat4";
		break;
	case VARIABLE_TYPE_MAT4X2:
		result = "mat4x2";
		break;
	case VARIABLE_TYPE_MAT4X3:
		result = "mat4x3";
		break;
	case VARIABLE_TYPE_UINT:
		result = "uint";
		break;
	case VARIABLE_TYPE_UVEC2:
		result = "uvec2";
		break;
	case VARIABLE_TYPE_UVEC3:
		result = "uvec3";
		break;
	case VARIABLE_TYPE_UVEC4:
		result = "uvec4";
		break;
	case VARIABLE_TYPE_VEC2:
		result = "vec2";
		break;
	case VARIABLE_TYPE_VEC3:
		result = "vec3";
		break;
	case VARIABLE_TYPE_VEC4:
		result = "vec4";
		break;

	default:
	{
		TCU_FAIL("Unrecognized variable type");
	}
	}; /* switch (type) */

	return result;
}

/** Check if GL context meets version requirements
 *
 * @param gl             Functions
 * @param required_major Minimum required MAJOR_VERSION
 * @param required_minor Minimum required MINOR_VERSION
 *
 * @return true if GL context version is at least as requested, false otherwise
 **/
bool Utils::isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor)
{
	glw::GLint major = 0;
	glw::GLint minor = 0;

	gl.getIntegerv(GL_MAJOR_VERSION, &major);
	gl.getIntegerv(GL_MINOR_VERSION, &minor);

	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");

	if (major > required_major)
	{
		/* Major is higher than required one */
		return true;
	}
	else if (major == required_major)
	{
		if (minor >= required_minor)
		{
			/* Major is equal to required one */
			/* Minor is higher than or equal to required one */
			return true;
		}
		else
		{
			/* Major is equal to required one */
			/* Minor is lower than required one */
			return false;
		}
	}
	else
	{
		/* Major is lower than required one */
		return false;
	}
}

/** Tells whether user-specified variable type corresponds to a matrix type.
 *
 *  @param type Variable type to use for the query.
 *
 *  @return true if the variable type describes a matrix, false otherwise.
 **/
bool Utils::isMatrixVariableType(_variable_type type)
{
	return (type == VARIABLE_TYPE_MAT2 || type == VARIABLE_TYPE_MAT3 || type == VARIABLE_TYPE_MAT4 ||
			type == VARIABLE_TYPE_MAT2X3 || type == VARIABLE_TYPE_MAT2X4 || type == VARIABLE_TYPE_MAT3X2 ||
			type == VARIABLE_TYPE_MAT3X4 || type == VARIABLE_TYPE_MAT4X2 || type == VARIABLE_TYPE_MAT4X3 ||
			type == VARIABLE_TYPE_DMAT2 || type == VARIABLE_TYPE_DMAT3 || type == VARIABLE_TYPE_DMAT4 ||
			type == VARIABLE_TYPE_DMAT2X3 || type == VARIABLE_TYPE_DMAT2X4 || type == VARIABLE_TYPE_DMAT3X2 ||
			type == VARIABLE_TYPE_DMAT3X4 || type == VARIABLE_TYPE_DMAT4X2 || type == VARIABLE_TYPE_DMAT4X3);
}

/** Tells whether user-specified variable type is scalar.
 *
 *  @return true if @param type is a scalar variable type, false otherwise.
 **/
bool Utils::isScalarVariableType(_variable_type type)
{
	bool result = false;

	switch (type)
	{
	case VARIABLE_TYPE_BOOL:
		result = true;
		break;
	case VARIABLE_TYPE_DOUBLE:
		result = true;
		break;
	case VARIABLE_TYPE_FLOAT:
		result = true;
		break;
	case VARIABLE_TYPE_INT:
		result = true;
		break;
	case VARIABLE_TYPE_UINT:
		result = true;
		break;
	default:
		break;
	}; /* switch (type) */

	return result;
}

/** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
 *
 * @param token           Token string
 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
 * @param text            String that will be used as replacement for <token>
 * @param string          String to work on
 **/
void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
						 std::string& string)
{
	const size_t text_length	= strlen(text);
	const size_t token_length   = strlen(token);
	const size_t token_position = string.find(token, search_position);

	string.replace(token_position, token_length, text, text_length);

	search_position = token_position + text_length;
}

/** Constructor.
 *
 *  @param context Rendering context.
 *
 **/
GPUShaderFP64Test1::GPUShaderFP64Test1(deqp::Context& context)
	: TestCase(context, "errors", "Verifies that various erroneous conditions related to double-precision "
								  "float uniform support & glUniform*() / glUniformMatrix*() API "
								  " are reported correctly.")
	, m_has_test_passed(true)
	, m_po_bool_arr_uniform_location(0)
	, m_po_bool_uniform_location(0)
	, m_po_bvec2_arr_uniform_location(0)
	, m_po_bvec2_uniform_location(0)
	, m_po_bvec3_arr_uniform_location(0)
	, m_po_bvec3_uniform_location(0)
	, m_po_bvec4_arr_uniform_location(0)
	, m_po_bvec4_uniform_location(0)
	, m_po_dmat2_arr_uniform_location(0)
	, m_po_dmat2_uniform_location(0)
	, m_po_dmat2x3_arr_uniform_location(0)
	, m_po_dmat2x3_uniform_location(0)
	, m_po_dmat2x4_arr_uniform_location(0)
	, m_po_dmat2x4_uniform_location(0)
	, m_po_dmat3_arr_uniform_location(0)
	, m_po_dmat3_uniform_location(0)
	, m_po_dmat3x2_arr_uniform_location(0)
	, m_po_dmat3x2_uniform_location(0)
	, m_po_dmat3x4_arr_uniform_location(0)
	, m_po_dmat3x4_uniform_location(0)
	, m_po_dmat4_arr_uniform_location(0)
	, m_po_dmat4_uniform_location(0)
	, m_po_dmat4x2_arr_uniform_location(0)
	, m_po_dmat4x2_uniform_location(0)
	, m_po_dmat4x3_arr_uniform_location(0)
	, m_po_dmat4x3_uniform_location(0)
	, m_po_double_arr_uniform_location(0)
	, m_po_double_uniform_location(0)
	, m_po_dvec2_arr_uniform_location(0)
	, m_po_dvec2_uniform_location(0)
	, m_po_dvec3_arr_uniform_location(0)
	, m_po_dvec3_uniform_location(0)
	, m_po_dvec4_arr_uniform_location(0)
	, m_po_dvec4_uniform_location(0)
	, m_po_float_arr_uniform_location(0)
	, m_po_float_uniform_location(0)
	, m_po_int_arr_uniform_location(0)
	, m_po_int_uniform_location(0)
	, m_po_ivec2_arr_uniform_location(0)
	, m_po_ivec2_uniform_location(0)
	, m_po_ivec3_arr_uniform_location(0)
	, m_po_ivec3_uniform_location(0)
	, m_po_ivec4_arr_uniform_location(0)
	, m_po_ivec4_uniform_location(0)
	, m_po_sampler_uniform_location(0)
	, m_po_uint_arr_uniform_location(0)
	, m_po_uint_uniform_location(0)
	, m_po_uvec2_arr_uniform_location(0)
	, m_po_uvec2_uniform_location(0)
	, m_po_uvec3_arr_uniform_location(0)
	, m_po_uvec3_uniform_location(0)
	, m_po_uvec4_arr_uniform_location(0)
	, m_po_uvec4_uniform_location(0)
	, m_po_vec2_arr_uniform_location(0)
	, m_po_vec2_uniform_location(0)
	, m_po_vec3_arr_uniform_location(0)
	, m_po_vec3_uniform_location(0)
	, m_po_vec4_arr_uniform_location(0)
	, m_po_vec4_uniform_location(0)
	, m_po_id(0)
	, m_vs_id(0)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects that may have been created during
 *  test execution.
 **/
void GPUShaderFP64Test1::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Returns a string describing GL API function represented by user-provided enum.
 *
 *  @param func Uniform function to return the string for.
 *
 *  @return As per description. [?] will be returned if the function was not recognized.
 **/
const char* GPUShaderFP64Test1::getUniformFunctionString(_uniform_function func)
{
	const char* result = "[?]";

	switch (func)
	{
	case UNIFORM_FUNCTION_1D:
		result = "glUniform1d";
		break;
	case UNIFORM_FUNCTION_1DV:
		result = "glUniform1dv";
		break;
	case UNIFORM_FUNCTION_2D:
		result = "glUniform2d";
		break;
	case UNIFORM_FUNCTION_2DV:
		result = "glUniform2dv";
		break;
	case UNIFORM_FUNCTION_3D:
		result = "glUniform3d";
		break;
	case UNIFORM_FUNCTION_3DV:
		result = "glUniform3dv";
		break;
	case UNIFORM_FUNCTION_4D:
		result = "glUniform4d";
		break;
	case UNIFORM_FUNCTION_4DV:
		result = "glUniform4dv";
		break;
	case UNIFORM_FUNCTION_MATRIX2DV:
		result = "glUniformMatrix2dv";
		break;
	case UNIFORM_FUNCTION_MATRIX2X3DV:
		result = "glUniformMatrix2x3dv";
		break;
	case UNIFORM_FUNCTION_MATRIX2X4DV:
		result = "glUniformMatrix2x4dv";
		break;
	case UNIFORM_FUNCTION_MATRIX3DV:
		result = "glUniformMatrix3dv";
		break;
	case UNIFORM_FUNCTION_MATRIX3X2DV:
		result = "glUniformMatrix3x2dv";
		break;
	case UNIFORM_FUNCTION_MATRIX3X4DV:
		result = "glUniformMatrix3x4dv";
		break;
	case UNIFORM_FUNCTION_MATRIX4DV:
		result = "glUniformMatrix4dv";
		break;
	case UNIFORM_FUNCTION_MATRIX4X2DV:
		result = "glUniformMatrix4x2dv";
		break;
	case UNIFORM_FUNCTION_MATRIX4X3DV:
		result = "glUniformMatrix4x3dv";
		break;
	default:
		break;
	}

	return result;
}

/** Returns name of an uniform bound to user-provided location.
 *
 *  @param location Location of the uniform to return the name for.
 *
 *  @return As per description. [?] will be returned if the location was not
 *          recognized.
 **/
const char* GPUShaderFP64Test1::getUniformNameForLocation(glw::GLint location)
{
	const char* result = "[?]";

	if (location == m_po_bool_arr_uniform_location)
		result = "uniform_bool_arr";
	else if (location == m_po_bool_uniform_location)
		result = "uniform_bool";
	else if (location == m_po_bvec2_arr_uniform_location)
		result = "uniform_bvec2_arr";
	else if (location == m_po_bvec2_uniform_location)
		result = "uniform_bvec2";
	else if (location == m_po_bvec3_arr_uniform_location)
		result = "uniform_bvec3_arr";
	else if (location == m_po_bvec3_uniform_location)
		result = "uniform_bvec3";
	else if (location == m_po_bvec4_arr_uniform_location)
		result = "uniform_bvec4_arr";
	else if (location == m_po_bvec4_uniform_location)
		result = "uniform_bvec4";
	else if (location == m_po_dmat2_arr_uniform_location)
		result = "uniform_dmat2_arr";
	else if (location == m_po_dmat2_uniform_location)
		result = "uniform_dmat2";
	else if (location == m_po_dmat2x3_arr_uniform_location)
		result = "uniform_dmat2x3_arr";
	else if (location == m_po_dmat2x3_uniform_location)
		result = "uniform_dmat2x3";
	else if (location == m_po_dmat2x4_arr_uniform_location)
		result = "uniform_dmat2x4_arr";
	else if (location == m_po_dmat2x4_uniform_location)
		result = "uniform_dmat2x4";
	else if (location == m_po_dmat3_arr_uniform_location)
		result = "uniform_dmat3_arr";
	else if (location == m_po_dmat3_uniform_location)
		result = "uniform_dmat3";
	else if (location == m_po_dmat3x2_arr_uniform_location)
		result = "uniform_dmat3x2_arr";
	else if (location == m_po_dmat3x2_uniform_location)
		result = "uniform_dmat3x2";
	else if (location == m_po_dmat3x4_arr_uniform_location)
		result = "uniform_dmat3x4_arr";
	else if (location == m_po_dmat3x4_uniform_location)
		result = "uniform_dmat3x4";
	else if (location == m_po_dmat4_arr_uniform_location)
		result = "uniform_dmat4_arr";
	else if (location == m_po_dmat4_uniform_location)
		result = "uniform_dmat4";
	else if (location == m_po_dmat4x2_arr_uniform_location)
		result = "uniform_dmat4x2_arr";
	else if (location == m_po_dmat4x2_uniform_location)
		result = "uniform_dmat4x2";
	else if (location == m_po_dmat4x3_arr_uniform_location)
		result = "uniform_dmat4x3_arr";
	else if (location == m_po_dmat4x3_uniform_location)
		result = "uniform_dmat4x3";
	else if (location == m_po_double_arr_uniform_location)
		result = "uniform_double_arr";
	else if (location == m_po_double_uniform_location)
		result = "uniform_double";
	else if (location == m_po_dvec2_arr_uniform_location)
		result = "uniform_dvec2_arr";
	else if (location == m_po_dvec2_uniform_location)
		result = "uniform_dvec2";
	else if (location == m_po_dvec3_arr_uniform_location)
		result = "uniform_dvec3_arr";
	else if (location == m_po_dvec3_uniform_location)
		result = "uniform_dvec3";
	else if (location == m_po_dvec4_arr_uniform_location)
		result = "uniform_dvec4_arr";
	else if (location == m_po_dvec4_uniform_location)
		result = "uniform_dvec4";
	else if (location == m_po_float_arr_uniform_location)
		result = "uniform_float_arr";
	else if (location == m_po_float_uniform_location)
		result = "uniform_float";
	else if (location == m_po_int_arr_uniform_location)
		result = "uniform_int_arr";
	else if (location == m_po_int_uniform_location)
		result = "uniform_int";
	else if (location == m_po_ivec2_arr_uniform_location)
		result = "uniform_ivec2_arr";
	else if (location == m_po_ivec2_uniform_location)
		result = "uniform_ivec2";
	else if (location == m_po_ivec3_arr_uniform_location)
		result = "uniform_ivec3_arr";
	else if (location == m_po_ivec3_uniform_location)
		result = "uniform_ivec3";
	else if (location == m_po_ivec4_arr_uniform_location)
		result = "uniform_ivec4_arr";
	else if (location == m_po_ivec4_uniform_location)
		result = "uniform_ivec4";
	else if (location == m_po_uint_arr_uniform_location)
		result = "uniform_uint_arr";
	else if (location == m_po_uint_uniform_location)
		result = "uniform_uint";
	else if (location == m_po_uvec2_arr_uniform_location)
		result = "uniform_uvec2_arr";
	else if (location == m_po_uvec2_uniform_location)
		result = "uniform_uvec2";
	else if (location == m_po_uvec3_arr_uniform_location)
		result = "uniform_uvec3_arr";
	else if (location == m_po_uvec3_uniform_location)
		result = "uniform_uvec3";
	else if (location == m_po_uvec4_arr_uniform_location)
		result = "uniform_uvec4_arr";
	else if (location == m_po_uvec4_uniform_location)
		result = "uniform_uvec4";
	else if (location == m_po_vec2_arr_uniform_location)
		result = "uniform_vec2_arr";
	else if (location == m_po_vec2_uniform_location)
		result = "uniform_vec2";
	else if (location == m_po_vec3_arr_uniform_location)
		result = "uniform_vec3_arr";
	else if (location == m_po_vec3_uniform_location)
		result = "uniform_vec3";
	else if (location == m_po_vec4_arr_uniform_location)
		result = "uniform_vec4_arr";
	else if (location == m_po_vec4_uniform_location)
		result = "uniform_vec4";

	return result;
}

/** Initializes all GL objects required to run the test. Also extracts locations of all
 *  uniforms used by the test.
 *
 *  This function can throw a TestError exception if the implementation misbehaves.
 */
void GPUShaderFP64Test1::initTest()
{
	glw::GLint			  compile_status = GL_FALSE;
	const glw::Functions& gl			 = m_context.getRenderContext().getFunctions();
	glw::GLint			  link_status	= GL_FALSE;

	/* Set up a program object using all new double-precision types */
	const char* vs_body =
		"#version 400\n"
		"\n"
		"uniform bool      uniform_bool;\n"
		"uniform bvec2     uniform_bvec2;\n"
		"uniform bvec3     uniform_bvec3;\n"
		"uniform bvec4     uniform_bvec4;\n"
		"uniform dmat2     uniform_dmat2;\n"
		"uniform dmat2x3   uniform_dmat2x3;\n"
		"uniform dmat2x4   uniform_dmat2x4;\n"
		"uniform dmat3     uniform_dmat3;\n"
		"uniform dmat3x2   uniform_dmat3x2;\n"
		"uniform dmat3x4   uniform_dmat3x4;\n"
		"uniform dmat4     uniform_dmat4;\n"
		"uniform dmat4x2   uniform_dmat4x2;\n"
		"uniform dmat4x3   uniform_dmat4x3;\n"
		"uniform double    uniform_double;\n"
		"uniform dvec2     uniform_dvec2;\n"
		"uniform dvec3     uniform_dvec3;\n"
		"uniform dvec4     uniform_dvec4;\n"
		"uniform float     uniform_float;\n"
		"uniform int       uniform_int;\n"
		"uniform ivec2     uniform_ivec2;\n"
		"uniform ivec3     uniform_ivec3;\n"
		"uniform ivec4     uniform_ivec4;\n"
		"uniform sampler2D uniform_sampler;\n"
		"uniform uint      uniform_uint;\n"
		"uniform uvec2     uniform_uvec2;\n"
		"uniform uvec3     uniform_uvec3;\n"
		"uniform uvec4     uniform_uvec4;\n"
		"uniform vec2      uniform_vec2;\n"
		"uniform vec3      uniform_vec3;\n"
		"uniform vec4      uniform_vec4;\n"
		"uniform bool      uniform_bool_arr   [2];\n"
		"uniform bvec2     uniform_bvec2_arr  [2];\n"
		"uniform bvec3     uniform_bvec3_arr  [2];\n"
		"uniform bvec4     uniform_bvec4_arr  [2];\n"
		"uniform dmat2     uniform_dmat2_arr  [2];\n"
		"uniform dmat2x3   uniform_dmat2x3_arr[2];\n"
		"uniform dmat2x4   uniform_dmat2x4_arr[2];\n"
		"uniform dmat3     uniform_dmat3_arr  [2];\n"
		"uniform dmat3x2   uniform_dmat3x2_arr[2];\n"
		"uniform dmat3x4   uniform_dmat3x4_arr[2];\n"
		"uniform dmat4     uniform_dmat4_arr  [2];\n"
		"uniform dmat4x2   uniform_dmat4x2_arr[2];\n"
		"uniform dmat4x3   uniform_dmat4x3_arr[2];\n"
		"uniform double    uniform_double_arr [2];\n"
		"uniform dvec2     uniform_dvec2_arr  [2];\n"
		"uniform dvec3     uniform_dvec3_arr  [2];\n"
		"uniform dvec4     uniform_dvec4_arr  [2];\n"
		"uniform float     uniform_float_arr  [2];\n"
		"uniform int       uniform_int_arr    [2];\n"
		"uniform ivec2     uniform_ivec2_arr  [2];\n"
		"uniform ivec3     uniform_ivec3_arr  [2];\n"
		"uniform ivec4     uniform_ivec4_arr  [2];\n"
		"uniform uint      uniform_uint_arr   [2];\n"
		"uniform uvec2     uniform_uvec2_arr  [2];\n"
		"uniform uvec3     uniform_uvec3_arr  [2];\n"
		"uniform uvec4     uniform_uvec4_arr  [2];\n"
		"uniform vec2      uniform_vec2_arr   [2];\n"
		"uniform vec3      uniform_vec3_arr   [2];\n"
		"uniform vec4      uniform_vec4_arr   [2];\n"
		"\n"
		"void main()\n"
		"{\n"
		"    gl_Position = vec4(0) + texture(uniform_sampler, vec2(0) );\n"
		"\n"
		"    if (uniform_bool        && uniform_bvec2.y        && uniform_bvec3.z        && uniform_bvec4.w        &&\n"
		"        uniform_bool_arr[1] && uniform_bvec2_arr[1].y && uniform_bvec3_arr[1].z && uniform_bvec4_arr[1].w)\n"
		"    {\n"
		"        double sum = uniform_dmat2       [0].x + uniform_dmat2x3       [0].x + uniform_dmat2x4       [0].x +\n"
		"                     uniform_dmat3       [0].x + uniform_dmat3x2       [0].x + uniform_dmat3x4       [0].x +\n"
		"                     uniform_dmat4       [0].x + uniform_dmat4x2       [0].x + uniform_dmat4x3       [0].x +\n"
		"                     uniform_dmat2_arr[0][0].x + uniform_dmat2x3_arr[0][0].x + uniform_dmat2x4_arr[0][0].x +\n"
		"                     uniform_dmat3_arr[0][0].x + uniform_dmat3x2_arr[0][0].x + uniform_dmat3x4_arr[0][0].x +\n"
		"                     uniform_dmat4_arr[0][0].x + uniform_dmat4x2_arr[0][0].x + uniform_dmat4x3_arr[0][0].x +\n"
		"                     uniform_double            + uniform_double_arr [0]      +\n"
		"                     uniform_dvec2.x           + uniform_dvec3.x             + uniform_dvec4.x        +\n"
		"                     uniform_dvec2_arr[0].x    + uniform_dvec3_arr[0].x      + uniform_dvec4_arr[0].x;\n"
		"        int   sum2 = uniform_int               + uniform_ivec2.x             + uniform_ivec3.x        +\n"
		"                     uniform_ivec4.x           + uniform_ivec2_arr[0].x      + uniform_ivec3_arr[0].x +\n"
		"                     uniform_ivec4_arr[0].x    + uniform_int_arr[0];\n"
		"        uint  sum3 = uniform_uint              + uniform_uvec2.x             + uniform_uvec3.x        +\n"
		"                     uniform_uvec4.x           + uniform_uint_arr[0]         + uniform_uvec2_arr[0].x +\n"
		"                     uniform_uvec3_arr[0].x    + uniform_uvec4_arr[0].x;\n"
		"        float sum4 = uniform_float             + uniform_float_arr[0]  + \n"
		"                     uniform_vec2.x            + uniform_vec2_arr[0].x + \n"
		"                     uniform_vec3.x            + uniform_vec3_arr[0].x + \n"
		"                     uniform_vec4.x            + uniform_vec4_arr[0].x;\n"
		"\n"
		"        if (sum * sum4 > intBitsToFloat(sum2) * uintBitsToFloat(sum3) )\n"
		"        {\n"
		"            gl_Position = vec4(1);\n"
		"        }\n"
		"    }\n"
		"}\n";

	m_po_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");

	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");

	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	gl.compileShader(m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

	if (compile_status != GL_TRUE)
	{
		TCU_FAIL("Shader compilation failed.");
	}

	gl.attachShader(m_po_id, m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");

	gl.linkProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (link_status != GL_TRUE)
	{
		TCU_FAIL("Program linking failed.");
	}

	m_po_bool_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_bool_arr[0]");
	m_po_bool_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bool");
	m_po_bvec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_bvec2_arr[0]");
	m_po_bvec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bvec2");
	m_po_bvec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_bvec3_arr[0]");
	m_po_bvec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bvec3");
	m_po_bvec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_bvec4_arr[0]");
	m_po_bvec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bvec4");
	m_po_dmat2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dmat2_arr[0]");
	m_po_dmat2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dmat2");
	m_po_dmat2x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3_arr[0]");
	m_po_dmat2x3_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat2x3");
	m_po_dmat2x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4_arr[0]");
	m_po_dmat2x4_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat2x4");
	m_po_dmat3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dmat3_arr[0]");
	m_po_dmat3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dmat3");
	m_po_dmat3x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2_arr[0]");
	m_po_dmat3x2_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat3x2");
	m_po_dmat3x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4_arr[0]");
	m_po_dmat3x4_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat3x4");
	m_po_dmat4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dmat4_arr[0]");
	m_po_dmat4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dmat4");
	m_po_dmat4x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2_arr[0]");
	m_po_dmat4x2_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat4x2");
	m_po_dmat4x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3_arr[0]");
	m_po_dmat4x3_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat4x3");
	m_po_double_arr_uniform_location  = gl.getUniformLocation(m_po_id, "uniform_double_arr[0]");
	m_po_double_uniform_location	  = gl.getUniformLocation(m_po_id, "uniform_double");
	m_po_dvec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dvec2_arr[0]");
	m_po_dvec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dvec2");
	m_po_dvec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dvec3_arr[0]");
	m_po_dvec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dvec3");
	m_po_dvec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dvec4_arr[0]");
	m_po_dvec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dvec4");
	m_po_float_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_float_arr[0]");
	m_po_float_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_float");
	m_po_int_arr_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_int_arr[0]");
	m_po_int_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_int");
	m_po_ivec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_ivec2_arr[0]");
	m_po_ivec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_ivec2");
	m_po_ivec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_ivec3_arr[0]");
	m_po_ivec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_ivec3");
	m_po_ivec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_ivec4_arr[0]");
	m_po_ivec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_ivec4");
	m_po_sampler_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_sampler");
	m_po_uint_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_uint_arr[0]");
	m_po_uint_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uint");
	m_po_uvec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_uvec2_arr[0]");
	m_po_uvec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uvec2");
	m_po_uvec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_uvec3_arr[0]");
	m_po_uvec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uvec3");
	m_po_uvec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_uvec4_arr[0]");
	m_po_uvec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uvec4");
	m_po_vec2_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_vec2_arr[0]");
	m_po_vec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_vec2");
	m_po_vec3_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_vec3_arr[0]");
	m_po_vec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_vec3");
	m_po_vec4_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_vec4_arr[0]");
	m_po_vec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_vec4");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");

	if (m_po_bool_arr_uniform_location == -1 || m_po_bool_uniform_location == -1 ||
		m_po_bvec2_arr_uniform_location == -1 || m_po_bvec2_uniform_location == -1 ||
		m_po_bvec3_arr_uniform_location == -1 || m_po_bvec3_uniform_location == -1 ||
		m_po_bvec4_arr_uniform_location == -1 || m_po_bvec4_uniform_location == -1 ||
		m_po_dmat2_arr_uniform_location == -1 || m_po_dmat2_uniform_location == -1 ||
		m_po_dmat2x3_arr_uniform_location == -1 || m_po_dmat2x3_uniform_location == -1 ||
		m_po_dmat2x4_arr_uniform_location == -1 || m_po_dmat2x4_uniform_location == -1 ||
		m_po_dmat3_arr_uniform_location == -1 || m_po_dmat3_uniform_location == -1 ||
		m_po_dmat3x2_arr_uniform_location == -1 || m_po_dmat3x2_uniform_location == -1 ||
		m_po_dmat3x4_arr_uniform_location == -1 || m_po_dmat3x4_uniform_location == -1 ||
		m_po_dmat4_arr_uniform_location == -1 || m_po_dmat4_uniform_location == -1 ||
		m_po_dmat4x2_arr_uniform_location == -1 || m_po_dmat4x2_uniform_location == -1 ||
		m_po_dmat4x3_arr_uniform_location == -1 || m_po_dmat4x3_uniform_location == -1 ||
		m_po_double_arr_uniform_location == -1 || m_po_double_uniform_location == -1 ||
		m_po_dvec2_arr_uniform_location == -1 || m_po_dvec2_uniform_location == -1 ||
		m_po_dvec3_arr_uniform_location == -1 || m_po_dvec3_uniform_location == -1 ||
		m_po_dvec4_arr_uniform_location == -1 || m_po_dvec4_uniform_location == -1 ||
		m_po_float_arr_uniform_location == -1 || m_po_float_uniform_location == -1 ||
		m_po_int_arr_uniform_location == -1 || m_po_int_uniform_location == -1 ||
		m_po_ivec2_arr_uniform_location == -1 || m_po_ivec2_uniform_location == -1 ||
		m_po_ivec3_arr_uniform_location == -1 || m_po_ivec3_uniform_location == -1 ||
		m_po_ivec4_arr_uniform_location == -1 || m_po_ivec4_uniform_location == -1 ||
		m_po_sampler_uniform_location == -1 || m_po_uint_arr_uniform_location == -1 ||
		m_po_uint_uniform_location == -1 || m_po_uvec2_arr_uniform_location == -1 ||
		m_po_uvec2_uniform_location == -1 || m_po_uvec3_arr_uniform_location == -1 ||
		m_po_uvec3_uniform_location == -1 || m_po_uvec4_arr_uniform_location == -1 ||
		m_po_uvec4_uniform_location == -1 || m_po_vec2_arr_uniform_location == -1 || m_po_vec2_uniform_location == -1 ||
		m_po_vec3_arr_uniform_location == -1 || m_po_vec3_uniform_location == -1 ||
		m_po_vec4_arr_uniform_location == -1 || m_po_vec4_uniform_location == -1)
	{
		TCU_FAIL("At last one of the required uniforms is considered inactive.");
	}
}

/** Tells wheter uniform at user-specified location represents a double-precision
 *  matrix uniform.
 *
 *  @param uniform_location Location of the uniform to use for the query.
 *
 *  @return Requested information.
 **/
bool GPUShaderFP64Test1::isMatrixUniform(glw::GLint uniform_location)
{
	return (uniform_location == m_po_dmat2_uniform_location || uniform_location == m_po_dmat2x3_uniform_location ||
			uniform_location == m_po_dmat2x4_uniform_location || uniform_location == m_po_dmat3_uniform_location ||
			uniform_location == m_po_dmat3x2_uniform_location || uniform_location == m_po_dmat3x4_uniform_location ||
			uniform_location == m_po_dmat4_uniform_location || uniform_location == m_po_dmat4x2_uniform_location ||
			uniform_location == m_po_dmat4x3_uniform_location);
}

/** Tells whether user-specified uniform function corresponds to one of the
 *  functions in glUniformMatrix*() class.
 *
 *  @param func Uniform function enum to use for the query.
 *
 *  @return true if the specified enum represents one of the glUniformMatrix*() functions,
 *          false otherwise.
 **/
bool GPUShaderFP64Test1::isMatrixUniformFunction(_uniform_function func)
{
	return (func == UNIFORM_FUNCTION_MATRIX2DV || func == UNIFORM_FUNCTION_MATRIX2X3DV ||
			func == UNIFORM_FUNCTION_MATRIX2X4DV || func == UNIFORM_FUNCTION_MATRIX3DV ||
			func == UNIFORM_FUNCTION_MATRIX3X2DV || func == UNIFORM_FUNCTION_MATRIX3X4DV ||
			func == UNIFORM_FUNCTION_MATRIX4DV || func == UNIFORM_FUNCTION_MATRIX4X2DV ||
			func == UNIFORM_FUNCTION_MATRIX4X3DV);
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test1::iterate()
{
	/* Do not execute the test if GL_ARB_texture_view is not supported */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
	}

	/* Initialize all ES objects required to run all the checks */
	initTest();

	/* Make sure GL_INVALID_OPERATION is generated by glUniform*() and
	 * glUniformMatrix*() functions if there is no current program object.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO();

	/* Make sure GL_INVALID_OPERATION is generated by glUniform*() if
	 * the size of the uniform variable declared in the shader does not
	 * match the size indicated by the command.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions();

	/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
	 * glUniformMatrix*() are used to load a uniform variable of type
	 * bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4,
	 * unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array
	 * of these.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions();

	/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
	 * glUniformMatrix*() are used to load incompatible double-typed
	 * uniforms, as presented below:
	 *
	 * I.    double-typed uniform configured by glUniform2d();
	 * II.   double-typed uniform configured by glUniform3d();
	 * III.  double-typed uniform configured by glUniform4d();
	 * IV.   double-typed uniform configured by glUniformMatrix*();
	 * V.    dvec2-typed  uniform configured by glUniform1d();
	 * VI.   dvec2-typed  uniform configured by glUniform3d();
	 * VII.  dvec2-typed  uniform configured by glUniform4d();
	 * VIII. dvec2-typed  uniform configured by glUniformMatrix*();
	 *
	 *                          (etc.)
	 *
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions();

	/* Make sure GL_INVALID_OPERATION is generated if <location> of
	 * glUniform*() and glUniformMatrix*() is an invalid uniform
	 * location for the current program object and location is not
	 * equal to -1.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation();

	/* Make sure GL_INVALID_VALUE is generated if <count> of
	 * glUniform*() (*dv() functions only) and glUniformMatrix*() is
	 * negative.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount();

	/* Make sure GL_INVALID_OPERATION is generated if <count> of
	 * glUniform*() (*dv() functions only) and glUniformMatrix*() is
	 * greater than 1 and the indicated uniform variable is not an
	 * array variable.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount();

	/* Make sure GL_INVALID_OPERATION is generated if a sampler is
	 * loaded by glUniform*() and glUniformMatrix*().
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers();

	/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
	 * glUniformMatrix*() is used to load values for uniforms of
	 * boolean types.
	 */
	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans();

	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
 *  glUniformMatrix*dv() functions is used to load a boolean uniform.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans()
{
	const double double_data[] = {
		1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
	};
	const glw::Functions& gl				  = m_context.getRenderContext().getFunctions();
	bool				  result			  = true;
	glw::GLint			  uniform_locations[] = { m_po_bool_arr_uniform_location,  m_po_bool_uniform_location,
									   m_po_bvec2_arr_uniform_location, m_po_bvec2_uniform_location,
									   m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location,
									   m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location };
	const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]);

	for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
		 ++n_uniform_function)
	{
		const _uniform_function uniform_function = (_uniform_function)n_uniform_function;

		for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
		{
			const glw::GLint uniform_location = uniform_locations[n_uniform_location];

			switch (uniform_function)
			{
			case UNIFORM_FUNCTION_1D:
				gl.uniform1d(uniform_location, 0.0);
				break;
			case UNIFORM_FUNCTION_2D:
				gl.uniform2d(uniform_location, 0.0, 1.0);
				break;
			case UNIFORM_FUNCTION_3D:
				gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
				break;
			case UNIFORM_FUNCTION_4D:
				gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
				break;

			case UNIFORM_FUNCTION_1DV:
				gl.uniform1dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_2DV:
				gl.uniform2dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_3DV:
				gl.uniform3dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_4DV:
				gl.uniform4dv(uniform_location, 1 /* count */, double_data);
				break;

			case UNIFORM_FUNCTION_MATRIX2DV:
				gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2X3DV:
				gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2X4DV:
				gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3DV:
				gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3X2DV:
				gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3X4DV:
				gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4DV:
				gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4X2DV:
				gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4X3DV:
				gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
				break;

			default:
			{
				TCU_FAIL("Unrecognized uniform function");
			}
			}

			/* Make sure GL_INVALID_OPERATION was generated by the call */
			const glw::GLenum error_code = gl.getError();

			if (error_code != GL_INVALID_OPERATION)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
								   << "() did not generate an error"
									  " when applied against a boolean uniform."
								   << tcu::TestLog::EndMessage;

				result = false;
			}
		} /* for (all bool uniforms) */
	}	 /* for (all uniform functions) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
 *  glUniformMatrix*dv() functions is used to load a sampler2D uniform.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers()
{
	const double double_data[] = {
		1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
	};
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
		 ++n_uniform_function)
	{
		_uniform_function uniform_function = (_uniform_function)n_uniform_function;

		switch (uniform_function)
		{
		case UNIFORM_FUNCTION_1D:
			gl.uniform1d(m_po_sampler_uniform_location, 0.0);
			break;
		case UNIFORM_FUNCTION_2D:
			gl.uniform2d(m_po_sampler_uniform_location, 0.0, 1.0);
			break;
		case UNIFORM_FUNCTION_3D:
			gl.uniform3d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0);
			break;
		case UNIFORM_FUNCTION_4D:
			gl.uniform4d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0, 3.0);
			break;

		case UNIFORM_FUNCTION_1DV:
			gl.uniform1dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
			break;
		case UNIFORM_FUNCTION_2DV:
			gl.uniform2dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
			break;
		case UNIFORM_FUNCTION_3DV:
			gl.uniform3dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
			break;
		case UNIFORM_FUNCTION_4DV:
			gl.uniform4dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
			break;

		case UNIFORM_FUNCTION_MATRIX2DV:
			gl.uniformMatrix2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX2X3DV:
			gl.uniformMatrix2x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX2X4DV:
			gl.uniformMatrix2x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX3DV:
			gl.uniformMatrix3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX3X2DV:
			gl.uniformMatrix3x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX3X4DV:
			gl.uniformMatrix3x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX4DV:
			gl.uniformMatrix4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX4X2DV:
			gl.uniformMatrix4x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX4X3DV:
			gl.uniformMatrix4x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;

		default:
		{
			TCU_FAIL("Unrecognized uniform function");
		}
		}

		/* Make sure GL_INVALID_OPERATION was generated by the call */
		const glw::GLenum error_code = gl.getError();

		if (error_code != GL_INVALID_OPERATION)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
							   << "() did not generate an error"
								  " when applied against a sampler uniform."
							   << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all uniform functions) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*dv() or
 *  glUniformMatrix*dv() functions is used to load a compatible uniform using an
 *  invalid <count> argument.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount()
{
	const glw::GLdouble double_values[16] = { 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
											  9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
	const glw::Functions&   gl					= m_context.getRenderContext().getFunctions();
	bool					result				= true;
	const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV,		  UNIFORM_FUNCTION_2DV,
													UNIFORM_FUNCTION_3DV,		  UNIFORM_FUNCTION_4DV,
													UNIFORM_FUNCTION_MATRIX2DV,   UNIFORM_FUNCTION_MATRIX2X3DV,
													UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
													UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
													UNIFORM_FUNCTION_MATRIX4DV,   UNIFORM_FUNCTION_MATRIX4X2DV,
													UNIFORM_FUNCTION_MATRIX4X3DV };
	const glw::GLint uniforms[] = {
		m_po_bool_uniform_location,	m_po_bvec2_uniform_location,  m_po_bvec3_uniform_location,
		m_po_bvec4_uniform_location,   m_po_dmat2_uniform_location,  m_po_dmat2x3_uniform_location,
		m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location,  m_po_dmat3x2_uniform_location,
		m_po_dmat3x4_uniform_location, m_po_dmat4_uniform_location,  m_po_dmat4x2_uniform_location,
		m_po_dmat4x3_uniform_location, m_po_double_uniform_location, m_po_dvec2_uniform_location,
		m_po_dvec3_uniform_location,   m_po_dvec4_uniform_location,  m_po_float_uniform_location,
		m_po_int_uniform_location,	 m_po_ivec2_uniform_location,  m_po_ivec3_uniform_location,
		m_po_ivec4_uniform_location,   m_po_uint_uniform_location,   m_po_uvec2_uniform_location,
		m_po_uvec3_uniform_location,   m_po_uvec4_uniform_location,  m_po_vec2_uniform_location,
		m_po_vec3_uniform_location,	m_po_vec4_uniform_location
	};

	const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
	const unsigned int n_uniforms		   = sizeof(uniforms) / sizeof(uniforms[0]);

	for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
	{
		_uniform_function uniform_function = uniform_functions[n_uniform_function];

		for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
		{
			glw::GLint uniform_location = uniforms[n_uniform];

			/* Make sure we only use glUniformMatrix*() functions with matrix uniforms,
			 * and glUniform*() functions with vector uniforms.
			 */
			bool is_matrix_uniform = isMatrixUniform(uniform_location);

			if (((false == is_matrix_uniform) && (true == isMatrixUniformFunction(uniform_function))) ||
				((true == is_matrix_uniform) && (false == isMatrixUniformFunction(uniform_function))))
			{
				continue;
			}

			/* Issue the call with an invalid <count> argument */
			switch (uniform_function)
			{
			case UNIFORM_FUNCTION_1DV:
				gl.uniform1dv(uniform_location, 2, double_values);
				break;
			case UNIFORM_FUNCTION_2DV:
				gl.uniform2dv(uniform_location, 2, double_values);
				break;
			case UNIFORM_FUNCTION_3DV:
				gl.uniform3dv(uniform_location, 2, double_values);
				break;
			case UNIFORM_FUNCTION_4DV:
				gl.uniform4dv(uniform_location, 2, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX2DV:
				gl.uniformMatrix2dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX2X3DV:
				gl.uniformMatrix2x3dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX2X4DV:
				gl.uniformMatrix2x4dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX3DV:
				gl.uniformMatrix3dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX3X2DV:
				gl.uniformMatrix3x2dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX3X4DV:
				gl.uniformMatrix3x4dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX4DV:
				gl.uniformMatrix4dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX4X2DV:
				gl.uniformMatrix4x2dv(uniform_location, 2, GL_FALSE, double_values);
				break;
			case UNIFORM_FUNCTION_MATRIX4X3DV:
				gl.uniformMatrix4x3dv(uniform_location, 2, GL_FALSE, double_values);
				break;

			default:
			{
				TCU_FAIL("Unrecognized uniform function");
			}
			} /* switch (uniform_function) */

			/* Make sure GL_INVALID_VALUE was generated */
			glw::GLenum error_code = gl.getError();

			if (error_code != GL_INVALID_OPERATION)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
								   << "() "
									  "was called with an invalid count argument but did not generate a "
									  "GL_INVALID_OPERATION error"
								   << tcu::TestLog::EndMessage;

				result = false;
			}
		} /* for (all non-arrayed uniforms) */
	}	 /* for (all uniform functions) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
 *  glUniformMatrix*dv() functions is used to load an uniform at an invalid location.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation()
{
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	/* Find the largest valid uniform location */
	const glw::GLint uniform_locations[] = {
		m_po_bool_arr_uniform_location,	m_po_bool_uniform_location,		  m_po_bvec2_arr_uniform_location,
		m_po_bvec2_uniform_location,	   m_po_bvec3_arr_uniform_location,   m_po_bvec3_uniform_location,
		m_po_bvec4_arr_uniform_location,   m_po_bvec4_uniform_location,		  m_po_dmat2_arr_uniform_location,
		m_po_dmat2_uniform_location,	   m_po_dmat2x3_arr_uniform_location, m_po_dmat2x3_uniform_location,
		m_po_dmat2x4_arr_uniform_location, m_po_dmat2x4_uniform_location,	 m_po_dmat3_arr_uniform_location,
		m_po_dmat3_uniform_location,	   m_po_dmat3x2_arr_uniform_location, m_po_dmat3x2_uniform_location,
		m_po_dmat3x4_arr_uniform_location, m_po_dmat3x4_uniform_location,	 m_po_dmat4_arr_uniform_location,
		m_po_dmat4_uniform_location,	   m_po_dmat4x2_arr_uniform_location, m_po_dmat4x2_uniform_location,
		m_po_dmat4x3_arr_uniform_location, m_po_dmat4x3_uniform_location,	 m_po_double_arr_uniform_location,
		m_po_double_uniform_location,	  m_po_dvec2_arr_uniform_location,   m_po_dvec2_uniform_location,
		m_po_dvec3_arr_uniform_location,   m_po_dvec3_uniform_location,		  m_po_dvec4_arr_uniform_location,
		m_po_dvec4_uniform_location,	   m_po_float_arr_uniform_location,   m_po_float_uniform_location,
		m_po_int_arr_uniform_location,	 m_po_int_uniform_location,		  m_po_ivec2_arr_uniform_location,
		m_po_ivec2_uniform_location,	   m_po_ivec3_arr_uniform_location,   m_po_ivec3_uniform_location,
		m_po_ivec4_arr_uniform_location,   m_po_ivec4_uniform_location,		  m_po_uint_arr_uniform_location,
		m_po_uint_uniform_location,		   m_po_uvec2_arr_uniform_location,   m_po_uvec2_uniform_location,
		m_po_uvec3_arr_uniform_location,   m_po_uvec3_uniform_location,		  m_po_uvec4_arr_uniform_location,
		m_po_uvec4_uniform_location,	   m_po_vec2_arr_uniform_location,	m_po_vec2_uniform_location,
		m_po_vec3_arr_uniform_location,	m_po_vec3_uniform_location,		  m_po_vec4_arr_uniform_location,
		m_po_vec4_uniform_location
	};
	const unsigned int n_uniform_locations	= sizeof(uniform_locations) / sizeof(uniform_locations[0]);
	glw::GLint		   valid_uniform_location = -1;

	for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
	{
		glw::GLint uniform_location = uniform_locations[n_uniform_location];

		if (uniform_location > valid_uniform_location)
		{
			valid_uniform_location = uniform_location;
		}
	} /* for (all  uniform locations) */

	/* Iterate through all uniform functions and make sure GL_INVALID_OPERATION error is always generated
	 * for invalid uniform location that is != -1
	 */
	const double double_data[] = {
		1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
	};
	const glw::GLint invalid_uniform_location = valid_uniform_location + 1;

	for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
		 ++n_uniform_function)
	{
		_uniform_function uniform_function = (_uniform_function)n_uniform_function;

		switch (uniform_function)
		{
		case UNIFORM_FUNCTION_1D:
			gl.uniform1d(invalid_uniform_location, 0.0);
			break;
		case UNIFORM_FUNCTION_2D:
			gl.uniform2d(invalid_uniform_location, 0.0, 1.0);
			break;
		case UNIFORM_FUNCTION_3D:
			gl.uniform3d(invalid_uniform_location, 0.0, 1.0, 2.0);
			break;
		case UNIFORM_FUNCTION_4D:
			gl.uniform4d(invalid_uniform_location, 0.0, 1.0, 2.0, 3.0);
			break;

		case UNIFORM_FUNCTION_1DV:
			gl.uniform1dv(invalid_uniform_location, 1 /* count */, double_data);
			break;
		case UNIFORM_FUNCTION_2DV:
			gl.uniform2dv(invalid_uniform_location, 1 /* count */, double_data);
			break;
		case UNIFORM_FUNCTION_3DV:
			gl.uniform3dv(invalid_uniform_location, 1 /* count */, double_data);
			break;
		case UNIFORM_FUNCTION_4DV:
			gl.uniform4dv(invalid_uniform_location, 1 /* count */, double_data);
			break;

		case UNIFORM_FUNCTION_MATRIX2DV:
			gl.uniformMatrix2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX2X3DV:
			gl.uniformMatrix2x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX2X4DV:
			gl.uniformMatrix2x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX3DV:
			gl.uniformMatrix3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX3X2DV:
			gl.uniformMatrix3x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX3X4DV:
			gl.uniformMatrix3x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX4DV:
			gl.uniformMatrix4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX4X2DV:
			gl.uniformMatrix4x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;
		case UNIFORM_FUNCTION_MATRIX4X3DV:
			gl.uniformMatrix4x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
			break;

		default:
		{
			TCU_FAIL("Unrecognized uniform function");
		}
		}

		const glw::GLenum error_code = gl.getError();

		if (error_code != GL_INVALID_OPERATION)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
							   << "() did not generate an error"
								  " when passed an invalid uniform location different from -1."
							   << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all uniform functions) */

	return result;
}

/** Verifies GL_INVALID_VALUE is generated if any of the glUniform*dv() or
 *  glUniformMatrix*dv() functions is used to load a compatible uniform using an
 *  invalid <count> argument of -1.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount()
{
	const glw::GLdouble double_values[16] = { 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
											  9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
	const glw::Functions&   gl					= m_context.getRenderContext().getFunctions();
	bool					result				= true;
	const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV,		  UNIFORM_FUNCTION_2DV,
													UNIFORM_FUNCTION_3DV,		  UNIFORM_FUNCTION_4DV,
													UNIFORM_FUNCTION_MATRIX2DV,   UNIFORM_FUNCTION_MATRIX2X3DV,
													UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
													UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
													UNIFORM_FUNCTION_MATRIX4DV,   UNIFORM_FUNCTION_MATRIX4X2DV,
													UNIFORM_FUNCTION_MATRIX4X3DV };
	const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);

	for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
	{
		_uniform_function uniform_function = uniform_functions[n_uniform_function];

		switch (uniform_function)
		{
		case UNIFORM_FUNCTION_1DV:
			gl.uniform1dv(m_po_double_arr_uniform_location, -1, double_values);
			break;
		case UNIFORM_FUNCTION_2DV:
			gl.uniform2dv(m_po_dvec2_arr_uniform_location, -1, double_values);
			break;
		case UNIFORM_FUNCTION_3DV:
			gl.uniform3dv(m_po_dvec3_arr_uniform_location, -1, double_values);
			break;
		case UNIFORM_FUNCTION_4DV:
			gl.uniform4dv(m_po_dvec4_arr_uniform_location, -1, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX2DV:
			gl.uniformMatrix2dv(m_po_dmat2_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX2X3DV:
			gl.uniformMatrix2x3dv(m_po_dmat2x3_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX2X4DV:
			gl.uniformMatrix2x4dv(m_po_dmat2x4_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX3DV:
			gl.uniformMatrix3dv(m_po_dmat3_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX3X2DV:
			gl.uniformMatrix3x2dv(m_po_dmat3x2_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX3X4DV:
			gl.uniformMatrix3x4dv(m_po_dmat3x4_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX4DV:
			gl.uniformMatrix4dv(m_po_dmat4_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX4X2DV:
			gl.uniformMatrix4x2dv(m_po_dmat4x2_arr_uniform_location, -1, GL_FALSE, double_values);
			break;
		case UNIFORM_FUNCTION_MATRIX4X3DV:
			gl.uniformMatrix4x3dv(m_po_dmat4x3_arr_uniform_location, -1, GL_FALSE, double_values);
			break;

		default:
		{
			TCU_FAIL("Unrecognized uniform function");
		}
		} /* switch (uniform_function) */

		/* Make sure GL_INVALID_VALUE was generated */
		glw::GLenum error_code = gl.getError();

		if (error_code != GL_INVALID_VALUE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
							   << "() "
								  "was called with a negative count argument but did not generate a "
								  "GL_INVALID_VALUE error"
							   << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all uniform functions) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
 *  glUniformMatrix*dv() functions is used to load an uniform that's incompatible with the
 *  function (as per spec).
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions()
{
	const double		  double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
	glw::GLenum			  error_code	= GL_NO_ERROR;
	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
	bool				  result		= true;

	const glw::GLint double_uniform_locations[] = { m_po_dmat2_uniform_location,   m_po_dmat2x3_uniform_location,
													m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location,
													m_po_dmat3x2_uniform_location, m_po_dmat3x4_uniform_location,
													m_po_dmat4_uniform_location,   m_po_dmat4x2_uniform_location,
													m_po_dmat4x3_uniform_location, m_po_double_uniform_location,
													m_po_dvec2_uniform_location,   m_po_dvec3_uniform_location,
													m_po_dvec4_uniform_location };
	const unsigned int n_double_uniform_locations =
		sizeof(double_uniform_locations) / sizeof(double_uniform_locations[0]);

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	for (unsigned int n_uniform_location = 0; n_uniform_location < n_double_uniform_locations; ++n_uniform_location)
	{
		glw::GLint uniform_location = double_uniform_locations[n_uniform_location];

		for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
			 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); function++)
		{
			_uniform_function e_function = static_cast<_uniform_function>(function);
			/* Exclude valid combinations */
			if (((uniform_location == m_po_dmat2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2DV)) ||
				((uniform_location == m_po_dmat2x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X3DV)) ||
				((uniform_location == m_po_dmat2x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X4DV)) ||
				((uniform_location == m_po_dmat3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3DV)) ||
				((uniform_location == m_po_dmat3x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X2DV)) ||
				((uniform_location == m_po_dmat3x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X4DV)) ||
				((uniform_location == m_po_dmat4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4DV)) ||
				((uniform_location == m_po_dmat4x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X2DV)) ||
				((uniform_location == m_po_dmat4x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X3DV)) ||
				((uniform_location == m_po_double_uniform_location) &&
				 ((e_function == UNIFORM_FUNCTION_1D) || (e_function == UNIFORM_FUNCTION_1DV))) ||
				((uniform_location == m_po_dvec2_uniform_location) &&
				 ((e_function == UNIFORM_FUNCTION_2D) || (e_function == UNIFORM_FUNCTION_2DV))) ||
				((uniform_location == m_po_dvec3_uniform_location) &&
				 ((e_function == UNIFORM_FUNCTION_3D) || (e_function == UNIFORM_FUNCTION_3DV))) ||
				((uniform_location == m_po_dvec4_uniform_location) &&
				 ((e_function == UNIFORM_FUNCTION_4D) || (e_function == UNIFORM_FUNCTION_4DV))))
			{
				continue;
			}

			switch (e_function)
			{
			case UNIFORM_FUNCTION_1D:
			{
				gl.uniform1d(uniform_location, double_data[0]);

				break;
			}

			case UNIFORM_FUNCTION_2D:
			{
				gl.uniform2d(uniform_location, double_data[0], double_data[1]);

				break;
			}

			case UNIFORM_FUNCTION_3D:
			{
				gl.uniform3d(uniform_location, double_data[0], double_data[1], double_data[2]);

				break;
			}

			case UNIFORM_FUNCTION_4D:
			{
				gl.uniform4d(uniform_location, double_data[0], double_data[1], double_data[2], double_data[3]);

				break;
			}

			case UNIFORM_FUNCTION_1DV:
				gl.uniform1dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_2DV:
				gl.uniform2dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_3DV:
				gl.uniform3dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_4DV:
				gl.uniform4dv(uniform_location, 1 /* count */, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2DV:
				gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2X3DV:
				gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2X4DV:
				gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3DV:
				gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3X2DV:
				gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3X4DV:
				gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4DV:
				gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4X2DV:
				gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4X3DV:
				gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
				break;

			default:
			{
				TCU_FAIL("Unrecognized function");
			}
			} /* switch (function) */

			/* Make sure GL_INVALID_OPERATION error was generated */
			error_code = gl.getError();

			if (error_code != GL_INVALID_OPERATION)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error [" << error_code
								   << "] was generated when a mismatched "
									  "double-precision uniform function "
								   << getUniformFunctionString(e_function) << "() was used to configure uniform "
								   << getUniformNameForLocation(uniform_location) << "." << tcu::TestLog::EndMessage;

				result = false;
			}
		} /* for (all uniform functions) */
	}	 /* for (all uniform locations) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
 *  glUniform*dv() functions is used to load an uniform, size of which is incompatible
 *  with the function.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions()
{
	const double		  double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
	glw::GLenum			  error_code	= GL_NO_ERROR;
	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
	bool				  result		= true;

	const int data[] = {
		/* API function */ /* Uniform location */ /* Count (dv functions only) */
		(int)UNIFORM_FUNCTION_2D, m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_2DV,
		m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_double_uniform_location, 0,
		(int)UNIFORM_FUNCTION_3DV, m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
		m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_double_uniform_location, 2,
		(int)UNIFORM_FUNCTION_1D, m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
		m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_dvec2_uniform_location, 0,
		(int)UNIFORM_FUNCTION_3DV, m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
		m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec2_uniform_location, 2,
		(int)UNIFORM_FUNCTION_1D, m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
		m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec3_uniform_location, 0,
		(int)UNIFORM_FUNCTION_2DV, m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
		m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec3_uniform_location, 2,
		(int)UNIFORM_FUNCTION_1D, m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
		m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec4_uniform_location, 0,
		(int)UNIFORM_FUNCTION_2DV, m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_3D,
		m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_3DV, m_po_dvec4_uniform_location, 2,
	};
	const unsigned int n_checks = sizeof(data) / sizeof(data[0]) / 3 /* entries per row */;

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	for (unsigned int n_check = 0; n_check < n_checks; ++n_check)
	{
		_uniform_function function		   = (_uniform_function)data[n_check * 3 + 0];
		int				  uniform_location = data[n_check * 3 + 1];
		int				  uniform_count	= data[n_check * 3 + 2];

		switch (function)
		{
		case UNIFORM_FUNCTION_1D:
			gl.uniform1d(uniform_location, 0.0);
			break;
		case UNIFORM_FUNCTION_1DV:
			gl.uniform1dv(uniform_location, uniform_count, double_data);
			break;
		case UNIFORM_FUNCTION_2D:
			gl.uniform2d(uniform_location, 0.0, 1.0);
			break;
		case UNIFORM_FUNCTION_2DV:
			gl.uniform2dv(uniform_location, uniform_count, double_data);
			break;
		case UNIFORM_FUNCTION_3D:
			gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
			break;
		case UNIFORM_FUNCTION_3DV:
			gl.uniform3dv(uniform_location, uniform_count, double_data);
			break;
		case UNIFORM_FUNCTION_4D:
			gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
			break;
		case UNIFORM_FUNCTION_4DV:
			gl.uniform4dv(uniform_location, uniform_count, double_data);
			break;

		default:
		{
			DE_ASSERT(false);
		}
		} /* switch (function) */

		error_code = gl.getError();
		if (error_code != GL_INVALID_OPERATION)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << getUniformFunctionString(function)
							   << "() function did not generate GL_INVALID_OPERATION error when called for"
								  " a uniform of incompatible size. (check index: "
							   << n_check << ")" << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all checks) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
 *  glUniform*dv() functions is used to load an uniform, type of which is incompatible
 *  with the function.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions()
{
	const double		  double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
	glw::GLenum			  error_code	= GL_NO_ERROR;
	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
	bool				  result		= true;

	const glw::GLint nondouble_uniform_locations[] = { m_po_bool_uniform_location,  m_po_bvec2_uniform_location,
													   m_po_bvec3_uniform_location, m_po_bvec4_uniform_location,
													   m_po_float_uniform_location, m_po_int_uniform_location,
													   m_po_ivec2_uniform_location, m_po_ivec3_uniform_location,
													   m_po_ivec4_uniform_location, m_po_uint_uniform_location,
													   m_po_uvec2_uniform_location, m_po_uvec3_uniform_location,
													   m_po_uvec4_uniform_location, m_po_vec2_uniform_location,
													   m_po_vec3_uniform_location,  m_po_vec4_uniform_location };
	const unsigned int n_nondouble_uniform_locations =
		sizeof(nondouble_uniform_locations) / sizeof(nondouble_uniform_locations[0]);

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	for (unsigned int n_uniform_location = 0; n_uniform_location < n_nondouble_uniform_locations; ++n_uniform_location)
	{
		glw::GLint uniform_location = nondouble_uniform_locations[n_uniform_location];

		for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
			 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); ++function)
		{
			switch (static_cast<_uniform_function>(function))
			{
			case UNIFORM_FUNCTION_1D:
				gl.uniform1d(uniform_location, 0.0);
				break;
			case UNIFORM_FUNCTION_1DV:
				gl.uniform1dv(uniform_location, 1, double_data);
				break;
			case UNIFORM_FUNCTION_2D:
				gl.uniform2d(uniform_location, 0.0, 1.0);
				break;
			case UNIFORM_FUNCTION_2DV:
				gl.uniform2dv(uniform_location, 1, double_data);
				break;
			case UNIFORM_FUNCTION_3D:
				gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
				break;
			case UNIFORM_FUNCTION_3DV:
				gl.uniform3dv(uniform_location, 1, double_data);
				break;
			case UNIFORM_FUNCTION_4D:
				gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
				break;
			case UNIFORM_FUNCTION_4DV:
				gl.uniform4dv(uniform_location, 1, double_data);
				break;

			case UNIFORM_FUNCTION_MATRIX2DV:
				gl.uniformMatrix2dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2X3DV:
				gl.uniformMatrix2x3dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX2X4DV:
				gl.uniformMatrix2x4dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3DV:
				gl.uniformMatrix3dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3X2DV:
				gl.uniformMatrix3x2dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX3X4DV:
				gl.uniformMatrix3x4dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4DV:
				gl.uniformMatrix4dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4X2DV:
				gl.uniformMatrix4x2dv(uniform_location, 1, GL_FALSE, double_data);
				break;
			case UNIFORM_FUNCTION_MATRIX4X3DV:
				gl.uniformMatrix4x3dv(uniform_location, 1, GL_FALSE, double_data);
				break;

			default:
			{
				DE_ASSERT(false);
			}
			} /* switch (function) */

			error_code = gl.getError();
			if (error_code != GL_INVALID_OPERATION)
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << getUniformFunctionString(static_cast<_uniform_function>(function))
								   << "() function did not generate GL_INVALID_OPERATION error when called for"
									  " a uniform of incompatible type."
								   << tcu::TestLog::EndMessage;

				result = false;
			}
		}
	} /* for (all checks) */

	return result;
}

/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
 *  glUniform*dv() functions are called without a bound program object.
 *
 *  @return true if the implementation was found to behave as expected, false otherwise.
 **/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO()
{
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST); function < static_cast<int>(UNIFORM_FUNCTION_COUNT);
		 function++)
	{
		const double data[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 };

		switch (static_cast<_uniform_function>(function))
		{
		case UNIFORM_FUNCTION_1D:
			gl.uniform1d(m_po_double_uniform_location, 0.0);
			break;
		case UNIFORM_FUNCTION_1DV:
			gl.uniform1dv(m_po_double_uniform_location, 1, data);
			break;
		case UNIFORM_FUNCTION_2D:
			gl.uniform2d(m_po_dvec2_uniform_location, 0.0, 1.0);
			break;
		case UNIFORM_FUNCTION_2DV:
			gl.uniform2dv(m_po_dvec2_uniform_location, 1, data);
			break;
		case UNIFORM_FUNCTION_3D:
			gl.uniform3d(m_po_dvec3_uniform_location, 0.0, 1.0, 2.0);
			break;
		case UNIFORM_FUNCTION_3DV:
			gl.uniform3dv(m_po_dvec3_uniform_location, 1, data);
			break;
		case UNIFORM_FUNCTION_4D:
			gl.uniform4d(m_po_dvec4_uniform_location, 0.0, 1.0, 2.0, 3.0);
			break;
		case UNIFORM_FUNCTION_4DV:
			gl.uniform4dv(m_po_dvec4_uniform_location, 1, data);
			break;

		case UNIFORM_FUNCTION_MATRIX2DV:
			gl.uniformMatrix2dv(m_po_dmat2_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX2X3DV:
			gl.uniformMatrix2x3dv(m_po_dmat2x3_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX2X4DV:
			gl.uniformMatrix2x4dv(m_po_dmat2x4_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX3DV:
			gl.uniformMatrix3dv(m_po_dmat3_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX3X2DV:
			gl.uniformMatrix3x2dv(m_po_dmat3x2_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX3X4DV:
			gl.uniformMatrix3x4dv(m_po_dmat3x4_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX4DV:
			gl.uniformMatrix4dv(m_po_dmat4_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX4X2DV:
			gl.uniformMatrix4x2dv(m_po_dmat4x2_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;
		case UNIFORM_FUNCTION_MATRIX4X3DV:
			gl.uniformMatrix4x3dv(m_po_dmat4x3_uniform_location, 1, GL_FALSE /* transpose */, data);
			break;

		default:
		{
			TCU_FAIL("Unrecognized uniform function");
		}
		} /* switch (func) */

		/* Query the error code */
		glw::GLenum error_code = gl.getError();

		if (error_code != GL_INVALID_OPERATION)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Implementation did not return GL_INVALID_OPERATION when "
							   << getUniformFunctionString(static_cast<_uniform_function>(function))
							   << "() was called without an active program object" << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all uniform functions) */

	return result;
}

/* Defeinitions of static const symbols declared in GPUShaderFP64Test2 */
const glw::GLuint GPUShaderFP64Test2::m_n_captured_results = 1024;
const glw::GLint  GPUShaderFP64Test2::m_result_failure	 = 2;
const glw::GLint  GPUShaderFP64Test2::m_result_success	 = 1;
const glw::GLuint GPUShaderFP64Test2::m_texture_width	  = 32;
const glw::GLuint GPUShaderFP64Test2::m_texture_height	 = m_n_captured_results / m_texture_width;
const glw::GLuint GPUShaderFP64Test2::m_transform_feedback_buffer_size =
	m_n_captured_results * sizeof(captured_varying_type);
const glw::GLchar* GPUShaderFP64Test2::m_uniform_block_name				  = "UniformBlock";
const glw::GLenum  GPUShaderFP64Test2::ARB_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263;

/** Constructor
 *
 * @param context Test context
 **/
GPUShaderFP64Test2::GPUShaderFP64Test2(deqp::Context& context)
	: TestCase(context, "max_uniform_components",
			   "Verifies that maximum allowed uniform components can be used as double-precision float types")
	, m_pDispatchCompute(0)
	, m_framebuffer_id(0)
	, m_texture_id(0)
	, m_transform_feedback_buffer_id(0)
	, m_uniform_buffer_id(0)
	, m_vertex_array_object_id(0)
{
	/* Nothing to be done */
}

/** Deinitialize test
 *
 **/
void GPUShaderFP64Test2::deinit()
{
	/* GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Clean frambuffer */
	if (0 != m_framebuffer_id)
	{
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		gl.deleteFramebuffers(1, &m_framebuffer_id);
		m_framebuffer_id = 0;
	}

	/* Clean texture */
	if (0 != m_texture_id)
	{
		gl.bindTexture(GL_TEXTURE_2D, 0);
		gl.bindImageTexture(0 /* unit */, 0 /* texture */, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
							GL_READ_ONLY, GL_RGBA8);
		gl.deleteTextures(1, &m_texture_id);
		m_texture_id = 0;
	}

	/* Clean buffers */
	if (0 != m_transform_feedback_buffer_id)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
		gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
		m_transform_feedback_buffer_id = 0;
	}

	if (0 != m_uniform_buffer_id)
	{
		gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
		gl.deleteBuffers(1, &m_uniform_buffer_id);
		m_uniform_buffer_id = 0;
	}

	/* Clean VAO */
	if (0 != m_vertex_array_object_id)
	{
		gl.bindVertexArray(0);
		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
		m_vertex_array_object_id = 0;
	}
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult GPUShaderFP64Test2::iterate()
{
	bool result = true;

	/* Check if extension is supported */
	if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
	}

	/* Initialize test */
	testInit();

	prepareShaderStages();
	prepareUniformTypes();

	/* For all shaders and uniform type combinations */
	for (std::vector<shaderStage>::const_iterator shader_stage = m_shader_stages.begin();
		 m_shader_stages.end() != shader_stage; ++shader_stage)
	{
		for (std::vector<uniformTypeDetails>::const_iterator uniform_type = m_uniform_types.begin();
			 m_uniform_types.end() != uniform_type; ++uniform_type)
		{
			/* Execute test */
			if (false == test(*shader_stage, *uniform_type))
			{
				result = false;
			}
		}
	}

	/* Set result */
	if (true == result)
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	/* Done */
	return tcu::TestNode::STOP;
}

/** Constructor
 *
 * @param n_columns Number of columns
 * @param n_rows    Number of rows
 **/
GPUShaderFP64Test2::uniformTypeDetails::uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows)
	: m_n_columns(n_columns), m_n_rows(n_rows)
{
	Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows);

	m_type_name = Utils::getVariableTypeString(type);
	m_type		= Utils::getGLDataTypeOfVariableType(type);
}

/** Get primitive type captured with transform feedback
 *
 * @param shader_stage Tested shader stage id
 *
 * @return Primitive type
 **/
glw::GLenum GPUShaderFP64Test2::getCapturedPrimitiveType(shaderStage shader_stage) const
{
	switch (shader_stage)
	{
	case GEOMETRY_SHADER:
	case TESS_CTRL_SHADER:
	case TESS_EVAL_SHADER:
	case VERTEX_SHADER:
		return GL_POINTS;
		break;

	default:
		return GL_NONE;
		break;
	}
}

/** Get primitive type drawn with DrawArrays
 *
 * @param shader_stage Tested shader stage id
 *
 * @return Primitive type
 **/
glw::GLenum GPUShaderFP64Test2::getDrawPrimitiveType(shaderStage shader_stage) const
{
	switch (shader_stage)
	{
	case FRAGMENT_SHADER:
		return GL_TRIANGLE_FAN;
		break;

	case GEOMETRY_SHADER:
	case VERTEX_SHADER:
		return GL_POINTS;
		break;

	case TESS_CTRL_SHADER:
	case TESS_EVAL_SHADER:
		return GL_PATCHES;
		break;

	default:
		return GL_NONE;
		break;
	}
}

/** Get maximum allowed number of uniform components
 *
 * @param shader_stage Tested shader stage id
 *
 * @return Maxmimum uniform components
 **/
glw::GLuint GPUShaderFP64Test2::getMaxUniformComponents(shaderStage shader_stage) const
{
	const glw::Functions& gl					 = m_context.getRenderContext().getFunctions();
	glw::GLint			  max_uniform_components = 0;
	glw::GLenum			  pname					 = 0;

	switch (shader_stage)
	{
	case COMPUTE_SHADER:
		pname = ARB_MAX_COMPUTE_UNIFORM_COMPONENTS;
		break;
	case FRAGMENT_SHADER:
		pname = GL_MAX_FRAGMENT_UNIFORM_COMPONENTS;
		break;
	case GEOMETRY_SHADER:
		pname = GL_MAX_GEOMETRY_UNIFORM_COMPONENTS;
		break;
	case TESS_CTRL_SHADER:
		pname = GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS;
		break;
	case TESS_EVAL_SHADER:
		pname = GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS;
		break;
	case VERTEX_SHADER:
		pname = GL_MAX_VERTEX_UNIFORM_COMPONENTS;
		break;
	}

	gl.getIntegerv(pname, &max_uniform_components);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");

	return max_uniform_components;
}

/** Get maximum size allowed for an uniform block
 *
 * @return Maxmimum uniform block size
 **/
glw::GLuint GPUShaderFP64Test2::getMaxUniformBlockSize() const
{
	const glw::Functions& gl					 = m_context.getRenderContext().getFunctions();
	glw::GLint			  max_uniform_block_size = 0;

	gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_block_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");

	return max_uniform_block_size;
}

/** Get number of components required to store single uniform of given type
 *
 * @param uniform_type Tested uniform type
 *
 * @return Number of components
 **/
glw::GLuint GPUShaderFP64Test2::getRequiredComponentsNumber(const uniformTypeDetails& uniform_type) const
{
	static const glw::GLuint type_size	 = 2; /* double takes 2 N */
	const glw::GLuint		 column_length = uniform_type.m_n_rows;

	if (1 == uniform_type.m_n_columns)
	{
		return type_size * column_length;
	}
	else
	{
		const glw::GLuint alignment = type_size * ((3 == column_length) ? 4 : column_length);

		return alignment * uniform_type.m_n_columns;
	}
}

/** Get size used for each member of a uniform array of a given type in a std140 column-major layout
 *
 * @param uniform_type Tested uniform type
 *
 * @return Size of a single member
 **/
glw::GLuint GPUShaderFP64Test2::getUniformTypeMemberSize(const uniformTypeDetails& uniform_type) const
{
	static const glw::GLuint vec4_size	 = 4 * Utils::getBaseVariableTypeComponentSize(Utils::VARIABLE_TYPE_FLOAT);
	const glw::GLuint		 column_length = uniform_type.m_n_rows;

	/** Size for a layout(std140, column_major) uniform_type uniform[] **/
	return vec4_size * ((column_length + 1) / 2) * uniform_type.m_n_columns;
}

/** Get the maximum amount of uniforms to be used in a shader stage for a given type
 *
 * @param shader_stage Tested shader stage id
 * @param uniform_type Tested uniform type
 *
 * @return Number of components
 **/
glw::GLuint GPUShaderFP64Test2::getAmountUniforms(shaderStage				shader_stage,
												  const uniformTypeDetails& uniform_type) const
{
	const glw::GLuint max_uniform_components   = getMaxUniformComponents(shader_stage);
	const glw::GLuint required_components	  = getRequiredComponentsNumber(uniform_type);
	const glw::GLuint n_uniforms			   = max_uniform_components / required_components;
	const glw::GLuint max_uniform_block_size   = getMaxUniformBlockSize();
	const glw::GLuint uniform_type_member_size = getUniformTypeMemberSize(uniform_type);
	const glw::GLuint max_uniforms			   = max_uniform_block_size / uniform_type_member_size;

	return max_uniforms < n_uniforms ? max_uniforms : n_uniforms;
}

/** Get name of shader stage
 *
 * @param shader_stage Tested shader stage id
 *
 * @return Name
 **/
const glw::GLchar* GPUShaderFP64Test2::getShaderStageName(shaderStage shader_stage) const
{
	switch (shader_stage)
	{
	case COMPUTE_SHADER:
		return "compute shader";
		break;
	case FRAGMENT_SHADER:
		return "fragment shader";
		break;
	case GEOMETRY_SHADER:
		return "geometry shader";
		break;
	case TESS_CTRL_SHADER:
		return "tesselation control shader";
		break;
	case TESS_EVAL_SHADER:
		return "tesselation evaluation shader";
		break;
	case VERTEX_SHADER:
		return "vertex shader";
		break;
	}

	return 0;
}

/** Inspect program to get: buffer_size, offset, strides and block index
 *
 * @param program_id          Program id
 * @param out_buffer_size     Size of uniform buffer
 * @param out_uniform_details Uniform offset and strides
 * @param uniform_block_index Uniform block index
 **/
void GPUShaderFP64Test2::inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms,
										const uniformTypeDetails& uniform_type, glw::GLint& out_buffer_size,
										uniformDetails& out_uniform_details, glw::GLuint uniform_block_index) const
{
	glw::GLint				 array_stride = 0;
	std::vector<glw::GLchar> extracted_uniform_name;
	const glw::Functions&	gl			   = m_context.getRenderContext().getFunctions();
	glw::GLuint				 index		   = 0;
	glw::GLint				 matrix_stride = 0;
	glw::GLint				 offset		   = 0;
	glw::GLsizei			 size		   = 0;
	glw::GLenum				 type		   = 0;
	const glw::GLchar*		 uniform_name  = 0;
	std::string				 uniform_name_str;
	std::stringstream		 uniform_name_stream;

	/* Get index of uniform block */
	uniform_block_index = gl.getUniformBlockIndex(program_id, m_uniform_block_name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex");

	if (GL_INVALID_INDEX == uniform_block_index)
	{
		TCU_FAIL("Unifom block is inactive");
	}

	/* Get size of uniform block */
	gl.getActiveUniformBlockiv(program_id, uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &out_buffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv");

	if (0 == out_buffer_size)
	{
		TCU_FAIL("Unifom block size is 0");
	}

	/* Prepare uniform name */
	uniform_name_stream << "uniform_array";

	uniform_name_str = uniform_name_stream.str();
	uniform_name	 = uniform_name_str.c_str();

	/* Get index of uniform */
	gl.getUniformIndices(program_id, 1 /* count */, &uniform_name, &index);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");

	if (GL_INVALID_INDEX == index)
	{
		TCU_FAIL("Unifom is inactive");
	}

	/* Verify getActiveUniform results */
	extracted_uniform_name.resize(uniform_name_str.length() * 2);

	gl.getActiveUniform(program_id, index, (glw::GLsizei)(uniform_name_str.length() * 2) /* bufSize */, 0, &size, &type,
						&extracted_uniform_name[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniform");

	if ((n_uniforms != size) || (uniform_type.m_type != type))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid GetActiveUniform results."
											<< " Size: " << size << " expected: " << n_uniforms << ". Type: " << type
											<< " expected: " << uniform_type.m_type
											<< ". Name: " << &extracted_uniform_name[0] << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid GetActiveUniform results");
	}

	/* Get offset of uniform */
	gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");

	if (-1 == offset)
	{
		TCU_FAIL("Unifom has invalid offset");
	}

	out_uniform_details.m_offset = offset;

	/* Get matrix stride of uniform */
	gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");

	if (-1 == matrix_stride)
	{
		TCU_FAIL("Unifom has invalid matrix stride");
	}

	out_uniform_details.m_matrix_stride = matrix_stride;

	/* Get array stride of uniform */
	gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_ARRAY_STRIDE, &array_stride);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");

	if (-1 == matrix_stride)
	{
		TCU_FAIL("Unifom has invalid matrix stride");
	}

	out_uniform_details.m_array_stride = array_stride;
}

/** Prepare source code for "boilerplate" shaders
 *
 * @param stage_specific_layout    String that will replace STAGE_SPECIFIC_LAYOUT token
 * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token
 * @param out_source_code          Source code
 **/
void GPUShaderFP64Test2::prepareBoilerplateShader(const glw::GLchar* stage_specific_layout,
												  const glw::GLchar* stage_specific_main_body,
												  std::string&		 out_source_code) const
{
	/* Shader template */
	static const glw::GLchar* boilerplate_shader_template_code = "#version 400 core\n"
																 "\n"
																 "precision highp float;\n"
																 "\n"
																 "STAGE_SPECIFIC_LAYOUT"
																 "void main()\n"
																 "{\n"
																 "STAGE_SPECIFIC_MAIN_BODY"
																 "}\n"
																 "\n";

	std::string string = boilerplate_shader_template_code;

	/* Tokens */
	static const glw::GLchar* body_token   = "STAGE_SPECIFIC_MAIN_BODY";
	static const glw::GLchar* layout_token = "STAGE_SPECIFIC_LAYOUT";

	size_t search_position = 0;

	/* Replace tokens */
	Utils::replaceToken(layout_token, search_position, stage_specific_layout, string);
	Utils::replaceToken(body_token, search_position, stage_specific_main_body, string);

	/* Store resuls */
	out_source_code = string;
}

/** Prepare program for given combination of shader stage and uniform type
 *
 * @param shader_stage     Shader stage
 * @param uniform_type     Uniform type
 * @param out_program_info Instance of programInfo
 **/
void GPUShaderFP64Test2::prepareProgram(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
										Utils::programInfo& out_program_info) const
{
	/* Stage specific layouts */
	static const glw::GLchar* geometry_shader_layout_code = "layout(points)                   in;\n"
															"layout(points, max_vertices = 1) out;\n"
															"\n";

	static const glw::GLchar* tess_ctrl_shader_layout_code = "layout(vertices = 1) out;\n"
															 "\n";

	static const glw::GLchar* tess_eval_shader_layout_code = "layout(isolines, point_mode) in;\n"
															 "\n";

	/* Stage specific main body */
	static const glw::GLchar* boilerplate_fragment_shader_body_code = "    discard;\n";

	static const glw::GLchar* boilerplate_tess_ctrl_shader_body_code = "    gl_TessLevelOuter[0] = 1.0;\n"
																	   "    gl_TessLevelOuter[1] = 1.0;\n"
																	   "    gl_TessLevelOuter[2] = 1.0;\n"
																	   "    gl_TessLevelOuter[3] = 1.0;\n"
																	   "    gl_TessLevelInner[0] = 1.0;\n"
																	   "    gl_TessLevelInner[1] = 1.0;\n";

	static const glw::GLchar* boilerplate_vertex_shader_body_code = "    gl_Position = vec4(1, 0, 0, 1);\n";

	static const glw::GLchar* corner_vertex_shader_body_code = "    if (0 == gl_VertexID)\n"
															   "    {\n"
															   "        gl_Position = vec4(-1, -1, 0, 1);\n"
															   "    }\n"
															   "    else if (1 == gl_VertexID)\n"
															   "    {\n"
															   "        gl_Position = vec4(-1, 1, 0, 1);\n"
															   "    }\n"
															   "    else if (2 == gl_VertexID)\n"
															   "    {\n"
															   "        gl_Position = vec4(1, 1, 0, 1);\n"
															   "    }\n"
															   "    else if (3 == gl_VertexID)\n"
															   "    {\n"
															   "        gl_Position = vec4(1, -1, 0, 1);\n"
															   "    }\n";

	static const glw::GLchar* passthrough_tess_eval_shader_body_code = "    result = tcs_tes_result[0];\n";

	static const glw::GLchar* test_shader_body_code = "\n    result = verification_result;\n";

	static const glw::GLchar* test_geometry_shader_body_code = "\n    result = verification_result;\n"
															   "\n"
															   "    EmitVertex();\n"
															   "    EndPrimitive();\n";

	static const glw::GLchar* test_tess_ctrl_shader_body_code =
		"\n    tcs_tes_result[gl_InvocationID] = verification_result;\n"
		"\n"
		"    gl_TessLevelOuter[0] = 1.0;\n"
		"    gl_TessLevelOuter[1] = 1.0;\n"
		"    gl_TessLevelOuter[2] = 1.0;\n"
		"    gl_TessLevelOuter[3] = 1.0;\n"
		"    gl_TessLevelInner[0] = 1.0;\n"
		"    gl_TessLevelInner[1] = 1.0;\n";

	/* In variables */
	static const glw::GLchar* test_tess_ctrl_shader_in_variable = "in  int tcs_tes_result[];\n";

	/* Out variables */
	static const glw::GLchar* test_fragment_shader_out_variable = "layout(location = 0) out int result;\n";

	static const glw::GLchar* test_tess_ctrl_shader_out_variable = "out int tcs_tes_result[];\n";

	static const glw::GLchar* test_shader_out_variable = "out int result;\n";

	/* Varying name */
	static const glw::GLchar* varying_name = "result";
	glw::GLuint				  n_varyings   = 1;

	/* Storage for ready shaders */
	std::string compute_shader_code;
	std::string fragment_shader_code;
	std::string geometry_shader_code;
	std::string tess_ctrl_shader_code;
	std::string tess_eval_shader_code;
	std::string vertex_shader_code;

	/* Storage for uniform definition and verification code */
	std::string uniform_definitions;
	std::string uniform_verification;

	/* Get uniform definition and verification code */
	prepareUniformDefinitions(shader_stage, uniform_type, uniform_definitions);
	prepareUniformVerification(shader_stage, uniform_type, uniform_verification);

	/* Prepare vertex shader */
	switch (shader_stage)
	{
	case FRAGMENT_SHADER:

		prepareBoilerplateShader("", corner_vertex_shader_body_code, vertex_shader_code);

		break;

	case GEOMETRY_SHADER:
	case TESS_CTRL_SHADER:
	case TESS_EVAL_SHADER:

		prepareBoilerplateShader("", boilerplate_vertex_shader_body_code, vertex_shader_code);

		break;

	case VERTEX_SHADER:

		prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */,
						  test_shader_out_variable /* out var */, uniform_verification.c_str() /* verification */,
						  test_shader_body_code /* body */, vertex_shader_code);

		break;

	default:
		break;
	}

	/* Prepare fragment shader */
	switch (shader_stage)
	{
	case FRAGMENT_SHADER:

		prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */,
						  test_fragment_shader_out_variable /* out var */,
						  uniform_verification.c_str() /* verification */, test_shader_body_code /* body */,
						  fragment_shader_code);

		break;

	case GEOMETRY_SHADER:
	case TESS_CTRL_SHADER:
	case TESS_EVAL_SHADER:
	case VERTEX_SHADER:

		prepareBoilerplateShader("" /* layout */, boilerplate_fragment_shader_body_code /* body */,
								 fragment_shader_code);

		break;

	default:
		break;
	}

	/* Prepare compute, tess_ctrl, tess_eval, geometry shaders */
	switch (shader_stage)
	{
	case COMPUTE_SHADER:

		prepareTestComputeShader(uniform_definitions.c_str(), uniform_verification.c_str(), compute_shader_code);

		break;

	case GEOMETRY_SHADER:

		prepareTestShader(geometry_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
						  "" /* in var */, test_shader_out_variable /* out var */,
						  uniform_verification.c_str() /* verification */, test_geometry_shader_body_code /* body */,
						  geometry_shader_code);

		break;

	case TESS_CTRL_SHADER:

		prepareTestShader(tess_ctrl_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
						  "" /* in var */, test_tess_ctrl_shader_out_variable /* out var */,
						  uniform_verification.c_str() /* verification */, test_tess_ctrl_shader_body_code /* body */,
						  tess_ctrl_shader_code);

		prepareTestShader(tess_eval_shader_layout_code /* layout */, "" /* uniforms */,
						  test_tess_ctrl_shader_in_variable /* in var */, test_shader_out_variable /* out var */,
						  "" /* verification */, passthrough_tess_eval_shader_body_code /* body */,
						  tess_eval_shader_code);

		break;

	case TESS_EVAL_SHADER:

		prepareBoilerplateShader(tess_ctrl_shader_layout_code /* layout */,
								 boilerplate_tess_ctrl_shader_body_code /* body */, tess_ctrl_shader_code);

		prepareTestShader(tess_eval_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
						  "" /* in var */, test_shader_out_variable /* out var */,
						  uniform_verification.c_str() /* verification */, test_shader_body_code /* body */,
						  tess_eval_shader_code);

		break;

	default:
		break;
	};

	/* Select shaders that will be used by program */
	const glw::GLchar* cs_c_str  = 0;
	const glw::GLchar* fs_c_str  = 0;
	const glw::GLchar* gs_c_str  = 0;
	const glw::GLchar* tcs_c_str = 0;
	const glw::GLchar* tes_c_str = 0;
	const glw::GLchar* vs_c_str  = 0;

	if (false == compute_shader_code.empty())
	{
		cs_c_str = compute_shader_code.c_str();
	}

	if (false == fragment_shader_code.empty())
	{
		fs_c_str = fragment_shader_code.c_str();
	}

	if (false == geometry_shader_code.empty())
	{
		gs_c_str = geometry_shader_code.c_str();
	}

	if (false == tess_ctrl_shader_code.empty())
	{
		tcs_c_str = tess_ctrl_shader_code.c_str();
	}

	if (false == tess_eval_shader_code.empty())
	{
		tes_c_str = tess_eval_shader_code.c_str();
	}

	if (false == vertex_shader_code.empty())
	{
		vs_c_str = vertex_shader_code.c_str();
	}

	/* Compute and fragment shader results are stored in texture, do not set varyings for transfrom feedback */
	if ((COMPUTE_SHADER == shader_stage) || (FRAGMENT_SHADER == shader_stage))
	{
		n_varyings = 0;
	}

	/* Build */
	out_program_info.build(cs_c_str, fs_c_str, gs_c_str, tcs_c_str, tes_c_str, vs_c_str, &varying_name, n_varyings);
}

/** Prepare collection of tested shader stages
 *
 */
void GPUShaderFP64Test2::prepareShaderStages()
{
	/* m_pDispatchCompute is initialized only if compute_shader are supproted and context is at least 4.2 */
	if (0 != m_pDispatchCompute)
	{
		m_shader_stages.push_back(COMPUTE_SHADER);
	}

	m_shader_stages.push_back(FRAGMENT_SHADER);
	m_shader_stages.push_back(GEOMETRY_SHADER);
	m_shader_stages.push_back(TESS_CTRL_SHADER);
	m_shader_stages.push_back(TESS_EVAL_SHADER);
	m_shader_stages.push_back(VERTEX_SHADER);
}

/** Prepare source code for "tested" shader stage
 *
 * @param stage_specific_layout    String that will replace STAGE_SPECIFIC_LAYOUT token
 * @param uniform_definitions      String that will replace UNIFORM_DEFINITIONS token
 * @param in_variable_definitions  String that will replace IN_VARIABLE_DEFINITION token
 * @param out_variable_definitions String that will replace OUT_VARIABLE_DEFINITION token
 * @param uniform_verification     String that will replace UNIFORM_VERIFICATION token
 * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token
 * @param out_source_code          Shader source code
 **/
void GPUShaderFP64Test2::prepareTestShader(const glw::GLchar* stage_specific_layout,
										   const glw::GLchar* uniform_definitions,
										   const glw::GLchar* in_variable_definitions,
										   const glw::GLchar* out_variable_definitions,
										   const glw::GLchar* uniform_verification,
										   const glw::GLchar* stage_specific_main_body,
										   std::string&		  out_source_code) const
{
	/* Shader template */
	static const glw::GLchar* test_shader_template_code = "#version 400 core\n"
														  "\n"
														  "precision highp float;\n"
														  "\n"
														  "STAGE_SPECIFIC_LAYOUT"
														  "UNIFORM_DEFINITIONS"
														  "IN_VARIABLE_DEFINITION"
														  "OUT_VARIABLE_DEFINITION"
														  "\n"
														  "void main()\n"
														  "{\n"
														  "UNIFORM_VERIFICATION"
														  "STAGE_SPECIFIC_MAIN_BODY"
														  "}\n"
														  "\n";

	std::string string = test_shader_template_code;

	/* Tokens */
	static const glw::GLchar* body_token	= "STAGE_SPECIFIC_MAIN_BODY";
	static const glw::GLchar* in_var_token  = "IN_VARIABLE_DEFINITION";
	static const glw::GLchar* layout_token  = "STAGE_SPECIFIC_LAYOUT";
	static const glw::GLchar* out_var_token = "OUT_VARIABLE_DEFINITION";
	static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS";
	static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION";

	size_t search_position = 0;

	/* Replace tokens */
	Utils::replaceToken(layout_token, search_position, stage_specific_layout, string);
	Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string);
	Utils::replaceToken(in_var_token, search_position, in_variable_definitions, string);
	Utils::replaceToken(out_var_token, search_position, out_variable_definitions, string);
	Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string);
	Utils::replaceToken(body_token, search_position, stage_specific_main_body, string);

	/* Store resuls */
	out_source_code = string;
}

/** Prepare source code for "tested" compute shaders
 *
 * @param uniform_definitions  String that will replace UNIFORM_DEFINITIONS token
 * @param uniform_verification String that will replace UNIFORM_VERIFICATION token
 * @param out_source_code      Source code
 **/
void GPUShaderFP64Test2::prepareTestComputeShader(const glw::GLchar* uniform_definitions,
												  const glw::GLchar* uniform_verification,
												  std::string&		 out_source_code) const
{
	/* Shader template */
	static const glw::GLchar* test_shader_template_code =
		"#version 420 core\n"
		"#extension GL_ARB_compute_shader          : require\n"
		"#extension GL_ARB_shader_image_load_store : require\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
		"\n"
		"UNIFORM_DEFINITIONS"
		"layout(r32i) writeonly uniform iimage2D result;\n"
		"\n"
		"void main()\n"
		"{\n"
		"UNIFORM_VERIFICATION"
		"\n"
		"    imageStore(result, ivec2(gl_WorkGroupID.xy), ivec4(verification_result, 0, 0, 0));\n"
		"}\n"
		"\n";

	std::string string = test_shader_template_code;

	/* Tokens */
	static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS";
	static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION";

	size_t search_position = 0;

	/* Replace tokens */
	Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string);
	Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string);

	/* Store resuls */
	out_source_code = string;
}

/** Prepare source code which defines uniforms for tested shader stage
 *
 * @param shader_stage    Shader stage id
 * @param uniform_type    Details of uniform type
 * @param out_source_code Source code
 **/
void GPUShaderFP64Test2::prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
												   std::string& out_source_code) const
{
	const glw::GLuint n_uniforms = getAmountUniforms(shader_stage, uniform_type);
	std::stringstream stream;

	/*
	 * layout(std140) uniform M_UNIFORM_BLOCK_NAME
	 * {
	 *     TYPE_NAME uniform_array[N_UNIFORMS];
	 * };
	 */
	stream << "layout(std140) uniform " << m_uniform_block_name << "\n"
																   "{\n";

	stream << "    " << uniform_type.m_type_name << " uniform_array[" << n_uniforms << "];\n";

	stream << "};\n\n";

	out_source_code = stream.str();
}

/** Prepare uniform buffer for test
 *
 * @param shader_stage Shader stage id
 * @param uniform_type Details of uniform type
 * @param program_info Program object info
 **/
void GPUShaderFP64Test2::prepareUniforms(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
										 const Utils::programInfo& program_info) const
{
	glw::GLint				  buffer_size	 = 0;
	glw::GLuint				  element_ordinal = 1;
	const glw::Functions&	 gl			  = m_context.getRenderContext().getFunctions();
	const glw::GLuint		  n_columns		  = uniform_type.m_n_columns;
	const glw::GLuint		  n_rows		  = uniform_type.m_n_rows;
	const glw::GLuint		  n_elements	  = n_columns * n_rows;
	uniformDetails			  uniform_details;
	const glw::GLuint		  program_id = program_info.m_program_object_id;
	const glw::GLint		  n_uniforms = getAmountUniforms(shader_stage, uniform_type);
	std::vector<glw::GLubyte> uniform_buffer_data;
	glw::GLuint				  uniform_block_index = 0;

	/* Get uniform details */
	inspectProgram(program_id, n_uniforms, uniform_type, buffer_size, uniform_details, uniform_block_index);

	/* Uniform offset and strides */
	const glw::GLuint array_stride   = uniform_details.m_array_stride;
	const glw::GLuint matrix_stride  = uniform_details.m_matrix_stride;
	const glw::GLuint uniform_offset = uniform_details.m_offset;

	/* Prepare storage for buffer data */
	uniform_buffer_data.resize(buffer_size);

	/* Prepare uniform data */
	for (glw::GLint i = 0; i < n_uniforms; ++i)
	{
		const glw::GLuint array_entry_offset = uniform_offset + i * array_stride;

		for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal)
		{
			const glw::GLuint   column		 = element / n_rows;
			const glw::GLuint   column_elem  = element % n_rows;
			const glw::GLdouble value		 = element_ordinal;
			const glw::GLuint   value_offset = static_cast<glw::GLuint>(array_entry_offset + column * matrix_stride +
																	  column_elem * sizeof(glw::GLdouble));
			glw::GLdouble* value_dst = (glw::GLdouble*)&uniform_buffer_data[value_offset];

			*value_dst = value;
		}
	}

	/* Update uniform buffer with new set of data */
	gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

	gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &uniform_buffer_data[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

	/* Bind uniform block to uniform buffer */
	gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0 /* offset */, buffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");

	gl.uniformBlockBinding(program_id, uniform_block_index, 0 /* binding */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding");
}

/** Prepare collection of tested uniform types
 *
 **/
void GPUShaderFP64Test2::prepareUniformTypes()
{
	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 1 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 2 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 3 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 4 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 2 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 3 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 4 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 2 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 3 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 4 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 2 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 3 /* n_rows */));
	m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 4 /* n_rows */));
}

/** Prepare source code that verifes uniform values
 *
 * @param shader_stage    Shader stage id
 * @param uniform_type    Details of uniform type
 * @param out_source_code Source code
 **/
void GPUShaderFP64Test2::prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
													std::string& out_source_code) const
{
	glw::GLuint		  element_ordinal = 1;
	const glw::GLuint n_columns		  = uniform_type.m_n_columns;
	const glw::GLuint n_rows		  = uniform_type.m_n_rows;
	const glw::GLuint n_elements	  = n_columns * n_rows;
	const glw::GLuint n_uniforms	  = getAmountUniforms(shader_stage, uniform_type);
	std::stringstream stream;

	/*
	 * int verification_result = M_RESULT_SUCCESS;
	 *
	 * for (int i = 0; i < N_UNIFORMS; ++i)
	 * {
	 *     if (TYPE_NAME(i * (N_ELEMENTS) + 1) != uniform_array[i])
	 *     {
	 *         verification_result = M_RESULT_FAILURE
	 *     }
	 * }
	 */
	stream << "    int verification_result = " << m_result_success << ";\n"
																	  "\n"
																	  "    for (int i = 0; i < "
		   << n_uniforms << "; ++i)\n"
							"    {\n"
							"        if ("
		   << uniform_type.m_type_name << "(";

	for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal)
	{
		stream << "i * (" << n_elements << ") + " << element + 1;

		if (n_elements != element + 1)
		{
			stream << ", ";
		}
	}

	stream << ") != uniform_array[i])\n"
			  "        {\n"
			  "           verification_result = "
		   << m_result_failure << ";\n"
								  "        }\n"
								  "    }\n";

	out_source_code = stream.str();
}

/** Execute test for given combination of "tested" shader stage and uniform type
 *
 * @param shader_stage Tested shader stage id
 * @param uniform_type Tested uniform type
 *
 * @return true if test passed, false otherwise
 **/
bool GPUShaderFP64Test2::test(shaderStage shader_stage, const uniformTypeDetails& uniform_type) const
{
	const glw::GLenum		draw_primitive = getDrawPrimitiveType(shader_stage);
	static const glw::GLint first_vertex   = 0;
	const glw::Functions&   gl			   = m_context.getRenderContext().getFunctions();
	const glw::GLsizei		n_vertices	 = (FRAGMENT_SHADER == shader_stage) ? 4 : m_n_captured_results;
	Utils::programInfo		program_info(m_context);
	bool					result = true;

	/* Prepare program */
	prepareProgram(shader_stage, uniform_type, program_info);

	gl.useProgram(program_info.m_program_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

	/* Prepare uniform buffer and bind it with uniform block */
	prepareUniforms(shader_stage, uniform_type, program_info);

	/* Prepare storage for test results */
	testBegin(program_info.m_program_object_id, shader_stage);

	/* Execute */
	if (COMPUTE_SHADER == shader_stage)
	{
		m_pDispatchCompute(m_texture_width, m_texture_height, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
	}
	else
	{
		gl.drawArrays(draw_primitive, first_vertex, n_vertices);
		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
	}

	/* Clean after test */
	testEnd(shader_stage);

	/* Check results */
	if (false == verifyResults(shader_stage))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Shader stage: " << getShaderStageName(shader_stage)
			<< ". Uniform type: " << uniform_type.m_type_name << tcu::TestLog::EndMessage;

		result = false;
	}

	return result;
}

/** Prepare transform feedback buffer, framebuffer or image unit for test results
 *
 * @param program_id   Program object id
 * @param shader_stage Tested shader stage id
 **/
void GPUShaderFP64Test2::testBegin(glw::GLuint program_id, shaderStage shader_stage) const
{
	std::vector<glw::GLint> buffer_data;
	const glw::GLenum		captured_primitive = getCapturedPrimitiveType(shader_stage);
	const glw::Functions&   gl				   = m_context.getRenderContext().getFunctions();

	/* Prepare buffer filled with m_result_failure */
	buffer_data.resize(m_n_captured_results);
	for (glw::GLuint i = 0; i < m_n_captured_results; ++i)
	{
		buffer_data[i] = m_result_failure;
	}

	/* Prepare buffer for test results */
	switch (shader_stage)
	{
	case GEOMETRY_SHADER:
	case TESS_CTRL_SHADER:
	case TESS_EVAL_SHADER:
	case VERTEX_SHADER:

		/* Verify getTransformFeedbackVarying results */
		{
			glw::GLsizei size = 0;
			glw::GLenum  type = 0;
			glw::GLchar  name[16];

			gl.getTransformFeedbackVarying(program_id, 0 /* index */, 16 /* bufSize */, 0 /* length */, &size, &type,
										   name);
			GLU_EXPECT_NO_ERROR(gl.getError(), "GetTransformFeedbackVarying");

			if ((1 != size) || (GL_INT != type) || (0 != strcmp("result", name)))
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Error. Invalid GetTransformFeedbackVarying results."
					<< " Size: " << size << " expected: " << 1 << ". Type: " << type << " expected: " << GL_INT
					<< ". Name: " << name << " expected: result" << tcu::TestLog::EndMessage;

				TCU_FAIL("Invalid GetTransformFeedbackVarying results");
			}
		}

		/* Create/clean transform feedback buffer */
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_size, &buffer_data[0], GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

		/* Set up transform feedback buffer */
		gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */,
						   m_transform_feedback_buffer_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");

		gl.beginTransformFeedback(captured_primitive);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

		break;

	case FRAGMENT_SHADER:

		/* Clean texture */
		gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");

		gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height,
						 GL_RED_INTEGER, GL_INT, &buffer_data[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");

		/* Set up texture as color attachment 0 */
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");

		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /* level */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");

		gl.viewport(0 /* x */, 0 /* y */, m_texture_width, m_texture_height);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");

		break;

	case COMPUTE_SHADER:

		/* Clean texture */
		gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");

		gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height,
						 GL_RED_INTEGER, GL_INT, &buffer_data[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");

		glw::GLint location = gl.getUniformLocation(program_id, "result");
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");

		if (-1 == location)
		{
			TCU_FAIL("Inactive uniform \"result\"");
		}

		gl.uniform1i(location, 0 /* first image unit */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");

		/* Bind texture to first image unit */
		gl.bindImageTexture(0 /* first image unit */, m_texture_id, 0 /* level */, GL_FALSE /* layered */,
							0 /* layer */, GL_WRITE_ONLY, GL_R32I);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");

		break;
	}
}

/** Unbind transform feedback buffer, framebuffer or image unit
 *
 * @param shader_stage Tested shader stage id
 **/
void GPUShaderFP64Test2::testEnd(shaderStage shader_stage) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	switch (shader_stage)
	{
	case GEOMETRY_SHADER:
	case TESS_CTRL_SHADER:
	case TESS_EVAL_SHADER:
	case VERTEX_SHADER:

		gl.endTransformFeedback();

		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

		break;

	case FRAGMENT_SHADER:

		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture_id */,
								0 /* level */);

		gl.bindTexture(GL_TEXTURE_2D, 0);

		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

		break;

	case COMPUTE_SHADER:

		gl.bindImageTexture(0 /* first image unit */, 0 /* texture_id */, 0 /* level */, GL_FALSE /* layered */,
							0 /* layer */, GL_WRITE_ONLY, GL_R32I);

		break;
	}
}

/** Initialize OpenGL objects for test
 *
 **/
void GPUShaderFP64Test2::testInit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* The test is in 4.0 group. However:
	 * - compute_shader is core since 4.3
	 * - compute_shader require at least version 4.2 of GL */
	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
	{
		m_pDispatchCompute = (arbDispatchComputeFunc)gl.dispatchCompute;
	}

	/* Tesselation patch set up */
	gl.patchParameteri(GL_PATCH_VERTICES, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");

	/* Generate FBO */
	gl.genFramebuffers(1, &m_framebuffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");

	/* Prepare texture */
	gl.genTextures(1, &m_texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");

	gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");

	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, m_texture_width, m_texture_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");

	/* Prepare transform feedback buffer */
	gl.genBuffers(1, &m_transform_feedback_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

	/* Generate uniform buffer */
	gl.genBuffers(1, &m_uniform_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

	/* Prepare VAO */
	gl.genVertexArrays(1, &m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");

	gl.bindVertexArray(m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
}

/** Result verification, expected result is that whole buffer is filled with m_result_success
 *
 * @param shader_stage Tested shader stage id
 **/
bool GPUShaderFP64Test2::verifyResults(shaderStage shader_stage) const
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if ((FRAGMENT_SHADER == shader_stage) || (COMPUTE_SHADER == shader_stage))
	{
		/* Verify contents of texture */

		/* Prepare storage for testure data */
		std::vector<glw::GLint> image_data;
		image_data.resize(m_texture_width * m_texture_height);

		/* Get texture contents */
		gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");

		gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");

		for (glw::GLuint y = 0; y < m_texture_width; ++y)
		{
			for (glw::GLuint x = 0; x < m_texture_height; ++x)
			{
				const glw::GLuint offset = y * m_texture_width + x;
				const glw::GLint  value  = image_data[offset];

				if (m_result_success != value)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "Error. Texture contents are wrong at (" << x << ", " << y << ")"
						<< tcu::TestLog::EndMessage;

					return false;
				}
			}
		}

		return true;
	}
	else
	{
		/* Verify contents of transform feedback buffer */

		bool result = true;

		/* Get transform feedback data */
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

		glw::GLint* feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");

		for (glw::GLuint i = 0; i < m_n_captured_results; ++i)
		{
			const glw::GLint value = feedback_data[i];

			if (m_result_success != value)
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "Error. Transform feedback buffer contents are wrong at " << i
													<< tcu::TestLog::EndMessage;

				result = false;
				break;
			}
		}

		/* Unmap transform feedback buffer */
		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");

		return result;
	}
}

/* Definitions of static const fields declared in GPUShaderFP64Test3 */
const glw::GLuint GPUShaderFP64Test3::m_result_failure = 0;
const glw::GLuint GPUShaderFP64Test3::m_result_success = 1;

const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_name			 = "UniformBlock";
const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_instance_name = "uniform_block";

const glw::GLchar* GPUShaderFP64Test3::m_varying_name_fs_out_fs_result   = "fs_out_fs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_gs_result	= "gs_fs_gs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tcs_result   = "gs_fs_tcs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tes_result   = "gs_fs_tes_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_vs_result	= "gs_fs_vs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_tcs_result = "tcs_tes_tcs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_vs_result  = "tcs_tes_vs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tcs_result  = "tes_gs_tcs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tes_result  = "tes_gs_tes_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_vs_result   = "tes_gs_vs_result";
const glw::GLchar* GPUShaderFP64Test3::m_varying_name_vs_tcs_vs_result   = "vs_tcs_vs_result";

/* Definitions of static const fields declared in GPUShaderFP64Test3::programInfo */
const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_offset			 = -1;
const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_matrix_stride	= -1;
const glw::GLint GPUShaderFP64Test3::programInfo::m_non_matrix_uniform_matrix_stride = 0;

/** Constructor
 *
 * @param context Test context
 **/
GPUShaderFP64Test3::GPUShaderFP64Test3(deqp::Context& context)
	: TestCase(context, "named_uniform_blocks",
			   "Verifies usage of \"double precision\" floats in \"named uniform block\"")
{
	/* Nothing to be done */
}

/** Deinitialize test
 *
 **/
void GPUShaderFP64Test3::deinit()
{
	/* GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Clean programs */
	m_packed_program.deinit(m_context);
	m_shared_program.deinit(m_context);
	m_std140_program.deinit(m_context);

	/* Clean frambuffer */
	if (0 != m_framebuffer_id)
	{
		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
		gl.deleteFramebuffers(1, &m_framebuffer_id);

		m_framebuffer_id = 0;
	}

	/* Clean texture */
	if (0 != m_color_texture_id)
	{
		gl.bindTexture(GL_TEXTURE_2D, 0);
		gl.deleteTextures(1, &m_color_texture_id);

		m_color_texture_id = 0;
	}

	/* Clean buffers */
	if (0 != m_transform_feedback_buffer_id)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
		gl.deleteBuffers(1, &m_transform_feedback_buffer_id);

		m_transform_feedback_buffer_id = 0;
	}

	if (0 != m_uniform_buffer_id)
	{
		gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
		gl.deleteBuffers(1, &m_uniform_buffer_id);

		m_uniform_buffer_id = 0;
	}

	/* Clean VAO */
	if (0 != m_vertex_array_object_id)
	{
		gl.bindVertexArray(0);
		gl.deleteVertexArrays(1, &m_vertex_array_object_id);

		m_vertex_array_object_id = 0;
	}
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult GPUShaderFP64Test3::iterate()
{
	bool result = true;

	/* Check if extension is supported */
	if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
	}

	/* Initialize test */
	testInit();

	/* Test "packed" uniform buffer layout */
	if (false == test(PACKED))
	{
		result = false;
	}

	/* Test "shared" uniform buffer layout */
	if (false == test(SHARED))
	{
		result = false;
	}

	/* Test "std140" uniform buffer layout */
	if (false == test(STD140))
	{
		result = false;
	}

	/* Set result */
	if (true == result)
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	/* Done */
	return tcu::TestNode::STOP;
}

/** Constructor
 *
 **/
GPUShaderFP64Test3::programInfo::programInfo()
	: m_fragment_shader_id(0)
	, m_geometry_shader_id(0)
	, m_program_object_id(0)
	, m_tesselation_control_shader_id(0)
	, m_tesselation_evaluation_shader_id(0)
	, m_vertex_shader_id(0)
	, m_buffer_size(0)
	, m_uniform_block_index(0)
{
	/* Nothing to be done here */
}

/** Compile shader
 *
 * @param context     Test context
 * @param shader_id   Shader object id
 * @param shader_code Shader source code
 **/
void GPUShaderFP64Test3::programInfo::compile(deqp::Context& context, glw::GLuint shader_id,
											  const glw::GLchar* shader_code) const
{
	/* GL entry points */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* Compilation status */
	glw::GLint status = GL_FALSE;

	/* Set source code */
	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");

	/* Compile */
	gl.compileShader(shader_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");

	/* Get compilation status */
	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");

	/* Log compilation error */
	if (GL_TRUE != status)
	{
		glw::GLint				 length = 0;
		std::vector<glw::GLchar> message;

		/* Error log length */
		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");

		/* Prepare storage */
		message.resize(length);

		/* Get error log */
		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");

		/* Log */
		context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
										  << &message[0] << "\nShader source\n"
										  << shader_code << tcu::TestLog::EndMessage;

		TCU_FAIL("Failed to compile shader");
	}
}

/** Cleans program and attached shaders
 *
 * @param context Test context
 **/
void GPUShaderFP64Test3::programInfo::deinit(deqp::Context& context)
{
	/* GL entry points */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* Restore default program */
	gl.useProgram(0);

	/* Clean program object */
	if (0 != m_program_object_id)
	{
		gl.deleteProgram(m_program_object_id);
		m_program_object_id = 0;
	}

	/* Clean shaders */
	if (0 != m_fragment_shader_id)
	{
		gl.deleteShader(m_fragment_shader_id);
		m_fragment_shader_id = 0;
	}

	if (0 != m_geometry_shader_id)
	{
		gl.deleteShader(m_geometry_shader_id);
		m_geometry_shader_id = 0;
	}

	if (0 != m_tesselation_control_shader_id)
	{
		gl.deleteShader(m_tesselation_control_shader_id);
		m_tesselation_control_shader_id = 0;
	}

	if (0 != m_tesselation_evaluation_shader_id)
	{
		gl.deleteShader(m_tesselation_evaluation_shader_id);
		m_tesselation_evaluation_shader_id = 0;
	}

	if (0 != m_vertex_shader_id)
	{
		gl.deleteShader(m_vertex_shader_id);
		m_vertex_shader_id = 0;
	}
}

/** Build program and query for uniform layout
 *
 * @param context                            Test context
 * @param uniform_details                  Collection of uniform details
 * @param fragment_shader_code               Fragment shader source code
 * @param geometry_shader_code               Geometry shader source code
 * @param tesselation_control_shader_code    Tesselation control shader source code
 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
 * @param vertex_shader_code                 Vertex shader source code
 **/
void GPUShaderFP64Test3::programInfo::init(deqp::Context& context, const std::vector<uniformDetails> uniform_details,
										   const glw::GLchar* fragment_shader_code,
										   const glw::GLchar* geometry_shader_code,
										   const glw::GLchar* tesselation_control_shader_code,
										   const glw::GLchar* tesselation_evaluation_shader_code,
										   const glw::GLchar* vertex_shader_code)
{
	/* GL entry points */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* Names of varyings to be captured with transform feedback */
	static const glw::GLchar* varying_names[] = { m_varying_name_gs_fs_gs_result, m_varying_name_gs_fs_tcs_result,
												  m_varying_name_gs_fs_tes_result, m_varying_name_gs_fs_vs_result };
	static const glw::GLuint n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);

	/* Create shader objects */
	m_fragment_shader_id			   = gl.createShader(GL_FRAGMENT_SHADER);
	m_geometry_shader_id			   = gl.createShader(GL_GEOMETRY_SHADER);
	m_tesselation_control_shader_id	= gl.createShader(GL_TESS_CONTROL_SHADER);
	m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
	m_vertex_shader_id				   = gl.createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");

	/* Create program object */
	m_program_object_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");

	/* Set up names of varyings to be captured with transform feedback */
	gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");

	/* Compile shaders */
	compile(context, m_fragment_shader_id, fragment_shader_code);
	compile(context, m_geometry_shader_id, geometry_shader_code);
	compile(context, m_tesselation_control_shader_id, tesselation_control_shader_code);
	compile(context, m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
	compile(context, m_vertex_shader_id, vertex_shader_code);

	/* Link program */
	link(context);

	/* Inspect program object */
	/* Get index of named uniform block */
	m_uniform_block_index = gl.getUniformBlockIndex(m_program_object_id, m_uniform_block_name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex");

	if (GL_INVALID_INDEX == m_uniform_block_index)
	{
		TCU_FAIL("Unifom block is inactive");
	}

	/* Get size of named uniform block */
	gl.getActiveUniformBlockiv(m_program_object_id, m_uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &m_buffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv");

	if (0 == m_buffer_size)
	{
		TCU_FAIL("Unifom block size is 0");
	}

	/* Get information about "double precision" uniforms */
	for (std::vector<uniformDetails>::const_iterator it = uniform_details.begin(), end = uniform_details.end();
		 end != it; ++it)
	{
		const glw::GLchar* uniform_name = 0;
		std::string		   uniform_name_str;
		std::stringstream  uniform_name_stream;
		glw::GLuint		   index		 = 0;
		glw::GLint		   offset		 = 0;
		glw::GLint		   matrix_stride = 0;

		/* Uniform name = UNIFORM_BLOCK_NAME.UNIFORM_NAME */
		uniform_name_stream << m_uniform_block_name << "." << it->m_name;

		uniform_name_str = uniform_name_stream.str();
		uniform_name	 = uniform_name_str.c_str();

		/* Get index of uniform */
		gl.getUniformIndices(m_program_object_id, 1 /* count */, &uniform_name, &index);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");

		if (GL_INVALID_INDEX == index)
		{
			TCU_FAIL("Unifom is inactive");
		}

		/* Get offset of uniform */
		gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");

		if (m_invalid_uniform_offset == offset)
		{
			TCU_FAIL("Unifom has invalid offset");
		}

		m_uniform_offsets.push_back(offset);

		/* Get matrix stride of uniform */
		gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");

		if (m_invalid_uniform_matrix_stride == offset)
		{
			TCU_FAIL("Unifom has invalid matrix stride");
		}

		m_uniform_matrix_strides.push_back(matrix_stride);
	}
}

/** Attach shaders and link program
 *
 * @param context Test context
 **/
void GPUShaderFP64Test3::programInfo::link(deqp::Context& context) const
{
	/* GL entry points */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* Link status */
	glw::GLint status = GL_FALSE;

	/* Attach shaders */
	gl.attachShader(m_program_object_id, m_fragment_shader_id);
	gl.attachShader(m_program_object_id, m_geometry_shader_id);
	gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
	gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
	gl.attachShader(m_program_object_id, m_vertex_shader_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");

	/* Link */
	gl.linkProgram(m_program_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");

	/* Get link status */
	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");

	/* Log link error */
	if (GL_TRUE != status)
	{
		glw::GLint				 length = 0;
		std::vector<glw::GLchar> message;

		/* Get error log length */
		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");

		message.resize(length);

		/* Get error log */
		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");

		/* Log */
		context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
										  << &message[0] << tcu::TestLog::EndMessage;

		TCU_FAIL("Failed to link program");
	}
}

/** Returns "predefined" values that will be used to fill uniform data
 *
 * @param type_ordinal Ordinal number of "double precision" uniform type
 * @param element      Index of element in uniform
 *
 * @return "Predefined" value
 **/
glw::GLdouble GPUShaderFP64Test3::getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const
{
	return m_base_type_ordinal + (13.0 * (glw::GLdouble)type_ordinal) +
		   ((m_base_element - (glw::GLdouble)element) / 4.0);
}

/** Returns a reference of programInfo instance specific for given buffer layout
 *
 * @param uniform_data_layout Buffer layout
 *
 * @return Reference to an instance of programInfo
 **/
const GPUShaderFP64Test3::programInfo& GPUShaderFP64Test3::getProgramInfo(uniformDataLayout uniform_data_layout) const
{
	const programInfo* program_info = 0;

	switch (uniform_data_layout)
	{
	case PACKED:

		program_info = &m_packed_program;

		break;

	case SHARED:

		program_info = &m_shared_program;

		break;

	case STD140:

		program_info = &m_std140_program;

		break;
	}

	return *program_info;
}

/** Get "name" of buffer layout
 *
 * @param uniform_data_layout Buffer layout
 *
 * @return "Name" of layout
 **/
const glw::GLchar* GPUShaderFP64Test3::getUniformLayoutName(uniformDataLayout uniform_data_layout) const
{
	const glw::GLchar* layout = "";

	switch (uniform_data_layout)
	{
	case PACKED:
		layout = "packed";
		break;
	case SHARED:
		layout = "shared";
		break;
	case STD140:
		layout = "std140";
		break;
	}

	return layout;
}

/** Prepare programInfo instance for specific buffer layout
 *
 * @param program_info        Instance of programInfo
 * @param uniform_data_layout Buffer layout
 **/
void GPUShaderFP64Test3::prepareProgram(programInfo& program_info, uniformDataLayout uniform_data_layout) const
{
	/* Storage for shader source code */
	std::stringstream fragment_shader_code;
	std::stringstream geometry_shader_code;
	std::stringstream tess_control_shader_code;
	std::stringstream tess_eval_shader_code;
	std::stringstream vertex_shader_code;

	/* Write preambles */
	writePreamble(fragment_shader_code, FRAGMENT_SHADER);
	writePreamble(geometry_shader_code, GEOMETRY_SHADER);
	writePreamble(tess_control_shader_code, TESS_CONTROL_SHADER);
	writePreamble(tess_eval_shader_code, TESS_EVAL_SHADER);
	writePreamble(vertex_shader_code, VERTEX_SHADER);

	/* Write definition of named uniform block */
	writeUniformBlock(fragment_shader_code, uniform_data_layout);
	writeUniformBlock(geometry_shader_code, uniform_data_layout);
	writeUniformBlock(tess_control_shader_code, uniform_data_layout);
	writeUniformBlock(tess_eval_shader_code, uniform_data_layout);
	writeUniformBlock(vertex_shader_code, uniform_data_layout);

	/* Write definitions of varyings */
	writeVaryingDeclarations(fragment_shader_code, FRAGMENT_SHADER);
	writeVaryingDeclarations(geometry_shader_code, GEOMETRY_SHADER);
	writeVaryingDeclarations(tess_control_shader_code, TESS_CONTROL_SHADER);
	writeVaryingDeclarations(tess_eval_shader_code, TESS_EVAL_SHADER);
	writeVaryingDeclarations(vertex_shader_code, VERTEX_SHADER);

	/* Write main routine */
	writeMainBody(fragment_shader_code, FRAGMENT_SHADER);
	writeMainBody(geometry_shader_code, GEOMETRY_SHADER);
	writeMainBody(tess_control_shader_code, TESS_CONTROL_SHADER);
	writeMainBody(tess_eval_shader_code, TESS_EVAL_SHADER);
	writeMainBody(vertex_shader_code, VERTEX_SHADER);

	/* Init programInfo instance */
	program_info.init(m_context, m_uniform_details, fragment_shader_code.str().c_str(),
					  geometry_shader_code.str().c_str(), tess_control_shader_code.str().c_str(),
					  tess_eval_shader_code.str().c_str(), vertex_shader_code.str().c_str());
}

/** Prepare uniform buffer
 *
 * @param program_info   Instance of programInfo
 * @param verify_offsets If uniform offsets should be verified against expected values
 *
 * @return false if uniform offsets verification result is failure, true otherwise
 **/
bool GPUShaderFP64Test3::prepareUniformBuffer(const programInfo& program_info, bool verify_offsets) const
{
	const glw::GLuint							buffer_size = program_info.m_buffer_size;
	const glw::Functions&						gl			= m_context.getRenderContext().getFunctions();
	bool										offset_verification_result = true;
	glw::GLuint									type_ordinal			   = 1;
	std::vector<uniformDetails>::const_iterator it_uniform_details		   = m_uniform_details.begin();
	std::vector<glw::GLint>::const_iterator		it_uniform_offsets		   = program_info.m_uniform_offsets.begin();
	std::vector<glw::GLint>::const_iterator it_uniform_matrix_strides = program_info.m_uniform_matrix_strides.begin();

	/* Prepare storage for uniform buffer data */
	std::vector<glw::GLubyte> buffer_data;
	buffer_data.resize(buffer_size);

	/* For each "double precision" uniform */
	for (/* start conditions already set up */; m_uniform_details.end() != it_uniform_details;
		 ++it_uniform_details, ++it_uniform_offsets, ++it_uniform_matrix_strides, ++type_ordinal)
	{
		const glw::GLint  matrix_stride  = *it_uniform_matrix_strides;
		const glw::GLuint n_columns		 = it_uniform_details->m_n_columns;
		const glw::GLuint n_elements	 = it_uniform_details->m_n_elements;
		const glw::GLuint column_length  = n_elements / n_columns;
		const glw::GLint  uniform_offset = *it_uniform_offsets;

		/* For each element of uniform */
		for (glw::GLuint element = 0; element < n_elements; ++element)
		{
			const glw::GLuint   column		= element / column_length;
			const glw::GLuint   column_elem = element % column_length;
			const glw::GLdouble value		= getExpectedValue(type_ordinal, element);
			const glw::GLuint   value_offset =
				static_cast<glw::GLuint>(uniform_offset + column * matrix_stride + column_elem * sizeof(glw::GLdouble));

			glw::GLdouble* value_dst = (glw::GLdouble*)&buffer_data[value_offset];

			/* Store value */
			*value_dst = value;
		}

		/* Uniform offset verification */
		if (true == verify_offsets)
		{
			const glw::GLint expected_offset = it_uniform_details->m_expected_std140_offset;

			if (expected_offset != uniform_offset)
			{
				if (true == offset_verification_result)
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage;
				}

				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Uniform: " << it_uniform_details->m_name
					<< " has offset: " << uniform_offset << ". Expected offset: " << expected_offset
					<< tcu::TestLog::EndMessage;

				offset_verification_result = false;
			}
		}
	}

	/* Update uniform buffer with prepared data */
	gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

	gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &buffer_data[0], GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

	/* Bind uniform buffer as data source for named uniform block */
	gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0, buffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");

	gl.uniformBlockBinding(program_info.m_program_object_id, program_info.m_uniform_block_index, 0 /* binding */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding");

	/* Done */
	return offset_verification_result;
}

/** Prepare data, execute draw call and verify results
 *
 * @param uniform_data_layout
 *
 * @return true if test pass, false otherwise
 **/
bool GPUShaderFP64Test3::test(uniformDataLayout uniform_data_layout) const
{
	bool				  are_offsets_verified		 = (STD140 == uniform_data_layout);
	const glw::Functions& gl						 = m_context.getRenderContext().getFunctions();
	bool				  offset_verification_result = true;
	const programInfo&	program_info				 = getProgramInfo(uniform_data_layout);
	bool				  result					 = true;

	/* Set up program */
	gl.useProgram(program_info.m_program_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

	/* Prepare uniform buffer */
	offset_verification_result = prepareUniformBuffer(program_info, are_offsets_verified);

	if (true == are_offsets_verified && false == offset_verification_result)
	{
		/* Offsets verification failure was already reported, add info about buffer layout */
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout)
											<< tcu::TestLog::EndMessage;

		result = false;
	}

	/* Set up transform feedback buffer */
	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_transform_feedback_buffer_id, 0, 4 * sizeof(glw::GLint));
	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

	/* Begin transform feedback */
	gl.beginTransformFeedback(GL_POINTS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

	/* Execute draw call for singe vertex */
	gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");

	/* Stop transform feedback */
	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");

	/* Verify results */
	if (false == verifyResults())
	{
		/* Result verificatioon failure was already reported, add info about layout */
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout)
											<< tcu::TestLog::EndMessage;

		result = false;
	}

	/* Done */
	return result;
}

void GPUShaderFP64Test3::testInit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Uniform block declaration with std140 offsets calculated
	 *                       | align | loc_req | begins | ends | offset in bytes | imp |
	 * ivec3   unused1[3]    |     4 |      12 |      0 |   12 |               0 |     |
	 * double  double_value  |     2 |       2 |     12 |   14 |              48 | XXX |
	 * bool    unused2       |     1 |       1 |     14 |   15 |              56 |     |
	 * dvec2   dvec2_value   |     4 |       4 |     16 |   20 |              64 | XXX |
	 * bvec3   unused3       |     4 |       4 |     20 |   24 |              80 |     |
	 * dvec3   dvec3_value   |     8 |       8 |     24 |   32 |              96 | XXX |
	 * int     unused4[3]    |     4 |      12 |     32 |   44 |             128 |     |
	 * dvec4   dvec4_value   |     8 |       8 |     48 |   56 |             192 | XXX |
	 * bool    unused5       |     1 |       1 |     56 |   57 |             224 |     |
	 * bool    unused6[2]    |     4 |       8 |     60 |   68 |             240 |     |
	 * dmat2   dmat2_value   |     4 |       8 |     68 |   76 |             272 | XXX |
	 * dmat3   dmat3_value   |     8 |      24 |     80 |  104 |             320 | XXX |
	 * bool    unused7       |     1 |       1 |    104 |  105 |             416 |     |
	 * dmat4   dmat4_value   |     8 |      32 |    112 |  144 |             448 | XXX |
	 * dmat2x3 dmat2x3_value |     8 |      16 |    144 |  160 |             576 | XXX |
	 * uvec3   unused8       |     4 |       4 |    160 |  164 |             640 |     |
	 * dmat2x4 dmat2x4_value |     8 |      16 |    168 |  184 |             672 | XXX |
	 * dmat3x2 dmat3x2_value |     4 |      12 |    184 |  196 |             736 | XXX |
	 * bool    unused9       |     1 |       1 |    196 |  197 |             784 |     |
	 * dmat3x4 dmat3x4_value |     8 |      24 |    200 |  224 |             800 | XXX |
	 * int     unused10      |     1 |       1 |    224 |  225 |             896 |     |
	 * dmat4x2 dmat4x2_value |     4 |      16 |    228 |  244 |             912 | XXX |
	 * dmat4x3 dmat4x3_value |     8 |      32 |    248 |  280 |             992 | XXX |
	 */

	/* Prepare "double precision" unfiorms' details */
	m_uniform_details.push_back(uniformDetails(48 /* off */, "double_value" /* name */, 1 /* n_columns */,
											   1 /* n_elements */, "double" /* type_name */));
	m_uniform_details.push_back(uniformDetails(64 /* off */, "dvec2_value" /* name */, 1 /* n_columns */,
											   2 /* n_elements */, "dvec2" /* type_name */));
	m_uniform_details.push_back(uniformDetails(96 /* off */, "dvec3_value" /* name */, 1 /* n_columns */,
											   3 /* n_elements */, "dvec3" /* type_name */));
	m_uniform_details.push_back(uniformDetails(192 /* off */, "dvec4_value" /* name */, 1 /* n_columns */,
											   4 /* n_elements */, "dvec4" /* type_name */));
	m_uniform_details.push_back(uniformDetails(272 /* off */, "dmat2_value" /* name */, 2 /* n_columns */,
											   4 /* n_elements */, "dmat2" /* type_name */));
	m_uniform_details.push_back(uniformDetails(320 /* off */, "dmat3_value" /* name */, 3 /* n_columns */,
											   9 /* n_elements */, "dmat3" /* type_name */));
	m_uniform_details.push_back(uniformDetails(448 /* off */, "dmat4_value" /* name */, 4 /* n_columns */,
											   16 /* n_elements */, "dmat4" /* type_name */));
	m_uniform_details.push_back(uniformDetails(576 /* off */, "dmat2x3_value" /* name */, 2 /* n_columns */,
											   6 /* n_elements */, "dmat2x3" /* type_name */));
	m_uniform_details.push_back(uniformDetails(672 /* off */, "dmat2x4_value" /* name */, 2 /* n_columns */,
											   8 /* n_elements */, "dmat2x4" /* type_name */));
	m_uniform_details.push_back(uniformDetails(736 /* off */, "dmat3x2_value" /* name */, 3 /* n_columns */,
											   6 /* n_elements */, "dmat3x2" /* type_name */));
	m_uniform_details.push_back(uniformDetails(800 /* off */, "dmat3x4_value" /* name */, 3 /* n_columns */,
											   12 /* n_elements */, "dmat3x4" /* type_name */));
	m_uniform_details.push_back(uniformDetails(912 /* off */, "dmat4x2_value" /* name */, 4 /* n_columns */,
											   8 /* n_elements */, "dmat4x2" /* type_name */));
	m_uniform_details.push_back(uniformDetails(992 /* off */, "dmat4x3_value" /* name */, 4 /* n_columns */,
											   12 /* n_elements */, "dmat4x3" /* type_name */));

	/* Get random values for getExpectedValue */
	m_base_element		= (glw::GLdouble)(rand() % 13);
	m_base_type_ordinal = (glw::GLdouble)(rand() % 213);

	/* Prepare programInfos for all buffer layouts */
	prepareProgram(m_packed_program, PACKED);
	prepareProgram(m_shared_program, SHARED);
	prepareProgram(m_std140_program, STD140);

	/* Generate buffers */
	gl.genBuffers(1, &m_transform_feedback_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

	gl.genBuffers(1, &m_uniform_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

	/* Prepare transform feedback buffer */
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), 0 /* data */, GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

	/* Prepare texture for color attachment 0 */
	gl.genTextures(1, &m_color_texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");

	gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");

	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_R32I, 1 /* width */, 1 /* height */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");

	/* Prepare FBO with color attachment 0 */
	gl.genFramebuffers(1, &m_framebuffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");

	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");

	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture_id,
							0 /* level */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");

	gl.viewport(0 /* x */, 0 /* y */, 1 /* width */, 1 /* height */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");

	/* Prepare VAO */
	gl.genVertexArrays(1, &m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");

	gl.bindVertexArray(m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");

	/* Tesselation patch set up */
	gl.patchParameteri(GL_PATCH_VERTICES, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
}

/** Verify contents of transform feedback buffer and framebuffer's color attachment 0
 *
 * @return true if all values are as expected, false otherwise
 **/
bool GPUShaderFP64Test3::verifyResults() const
{
	glw::GLint*			  feedback_data			  = 0;
	bool				  fragment_shader_result  = false;
	bool				  geometry_shader_result  = false;
	const glw::Functions& gl					  = m_context.getRenderContext().getFunctions();
	bool				  tess_ctrl_shader_result = false;
	bool				  tess_eval_shader_result = false;
	bool				  vertex_shader_result	= false;

	/* Prepare storage for testure data */
	std::vector<glw::GLint> image_data;
	image_data.resize(1);

	/* Get texture contents */
	gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");

	gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");

	/* Get transform feedback data */
	feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");

	/* Verify results */
	fragment_shader_result  = (m_result_success == image_data[0]);
	geometry_shader_result  = (m_result_success == feedback_data[0]);
	tess_ctrl_shader_result = (m_result_success == feedback_data[1]);
	tess_eval_shader_result = (m_result_success == feedback_data[2]);
	vertex_shader_result	= (m_result_success == feedback_data[3]);

	/* Unmap transform feedback buffer */
	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");

	/* Set result */
	if (true != (fragment_shader_result && geometry_shader_result && tess_ctrl_shader_result &&
				 tess_eval_shader_result && vertex_shader_result))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage;

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Vertex shader stage result: " << vertex_shader_result
											<< tcu::TestLog::EndMessage;

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Tesselation control shader stage result: " << tess_ctrl_shader_result
											<< tcu::TestLog::EndMessage;

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Tesselation evaluation shader stage result: " << tess_eval_shader_result
											<< tcu::TestLog::EndMessage;

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Geometry shader stage result: " << geometry_shader_result
											<< tcu::TestLog::EndMessage;

		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "Fragment shader stage result: " << fragment_shader_result
											<< tcu::TestLog::EndMessage;

		return false;
	}
	else
	{
		return true;
	}
}

/** Write main routine of <shader_stage> shader to stream
 *
 * @param stream       Output stream with source code of shader
 * @param shader_stage Shader stage
 **/
void GPUShaderFP64Test3::writeMainBody(std::ostream& stream, shaderStage shader_stage) const
{
	glw::GLuint		   type_ordinal = 1;
	const glw::GLchar* varying_name = "";

	/* Select name for varying that will hold result of "that" shader_stage */
	switch (shader_stage)
	{
	case FRAGMENT_SHADER:
		varying_name = m_varying_name_fs_out_fs_result;
		break;
	case GEOMETRY_SHADER:
		varying_name = m_varying_name_gs_fs_gs_result;
		break;
	case TESS_CONTROL_SHADER:
		varying_name = m_varying_name_tcs_tes_tcs_result;
		break;
	case TESS_EVAL_SHADER:
		varying_name = m_varying_name_tes_gs_tes_result;
		break;
	case VERTEX_SHADER:
		varying_name = m_varying_name_vs_tcs_vs_result;
		break;
	}

	/* void main() */
	stream << "void main()\n"
			  "{\n";

	/* Tesselation levels output */
	if (TESS_CONTROL_SHADER == shader_stage)
	{
		stream << "gl_TessLevelOuter[0] = 1.0;\n"
				  "gl_TessLevelOuter[1] = 1.0;\n"
				  "gl_TessLevelOuter[2] = 1.0;\n"
				  "gl_TessLevelOuter[3] = 1.0;\n"
				  "gl_TessLevelInner[0] = 1.0;\n"
				  "gl_TessLevelInner[1] = 1.0;\n"
				  "\n";
	}

	/* For each "double precision" uniform
	 *
	 * [else] if (TYPE_NAME(PREDIFINED_VALUES) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME)
	 * {
	 *     VARYING_NAME = m_result_failure;
	 * }
	 */
	for (std::vector<uniformDetails>::const_iterator it = m_uniform_details.begin(), end = m_uniform_details.end();
		 end != it; ++it, ++type_ordinal)
	{
		stream << "    ";

		/* First comparison is done with if, next with else if */
		if (1 != type_ordinal)
		{
			stream << "else ";
		}

		/* if (TYPE_NAME( */
		stream << "if (" << it->m_type_name << "(";

		/* PREDIFINED_VALUES */
		for (glw::GLuint element = 0; element < it->m_n_elements; ++element)
		{
			stream << getExpectedValue(type_ordinal, element);

			/* Separate with comma */
			if (it->m_n_elements != element + 1)
			{
				stream << ", ";
			}
		}

		/*
		 * ) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME)
		 * {
		 *     VARYING_NAME
		 */
		stream << ") != " << m_uniform_block_instance_name << "." << it->m_name << ")\n"
																				   "    {\n"
																				   "        "
			   << varying_name;

		/* Tesselation control outputs have to be arrays indexed with gl_InvocationID */
		if (TESS_CONTROL_SHADER == shader_stage)
		{
			stream << "[gl_InvocationID]";
		}

		/*
		 * = m_result_failure;
		 * }
		 */
		stream << " = " << m_result_failure << ";\n"
			   << "    }\n";
	}

	/* If all comparisons are ok
	 *
	 *     else
	 *     {
	 *         VARYING_NAME = m_result_success;
	 *     }
	 */

	/*
	 * else
	 * {
	 *     VARYING_NAME
	 */
	stream << "    else\n"
			  "    {\n"
			  "        "
		   << varying_name;

	/* Tesselation control outputs have to be arrays indexed with gl_InvocationID */
	if (TESS_CONTROL_SHADER == shader_stage)
	{
		stream << "[gl_InvocationID]";
	}

	/*
	 * = m_result_success;
	 * }
	 *
	 */
	stream << " = " << m_result_success << ";\n"
		   << "    }\n"
		   << "\n";

	/* For each pair of "input/output" varyings
	 *
	 * OUTPUT_VARYING_NAME = INPUT_VARYING_NAME;
	 **/
	writeVaryingPassthrough(stream, shader_stage);

	/* Geometry shader have to emit vertex */
	if (GEOMETRY_SHADER == shader_stage)
	{
		stream << "\n"
				  "gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"
				  "EmitVertex();\n"
				  "EndPrimitive();\n";
	}

	/* Close scope of main */
	stream << "}\n\n";
}

/** Write shader preamble to stream
 *
 * @param stream       Output stream with source code of shader
 * @param shader_stage Shader stage
 **/
void GPUShaderFP64Test3::writePreamble(std::ostream& stream, shaderStage shader_stage) const
{
	stream << "#version 400 core\n"
			  "\n"
			  "precision highp float;\n"
			  "\n";

	switch (shader_stage)
	{
	case FRAGMENT_SHADER:
		break;
	case GEOMETRY_SHADER:
		stream << "layout(points)                   in;\n"
				  "layout(points, max_vertices = 1) out;\n"
				  "\n";
		break;
	case TESS_CONTROL_SHADER:
		stream << "layout(vertices = 1) out;\n"
				  "\n";
		break;
	case TESS_EVAL_SHADER:
		stream << "layout(isolines, point_mode) in;\n"
				  "\n";
		break;
	case VERTEX_SHADER:
		break;
	}
}

/** Write name uniform blcok definition with specific layout to stream
 *
 * @param stream              Output stream with source code of shader
 * @param uniform_data_layout Buffer layout
 **/
void GPUShaderFP64Test3::writeUniformBlock(std::ostream& stream, uniformDataLayout uniform_data_layout) const
{
	const glw::GLchar* layout = getUniformLayoutName(uniform_data_layout);

	stream << "layout(" << layout << ") uniform " << m_uniform_block_name << "\n"
																			 "{\n"
																			 "    ivec3   unused1[3];\n"
																			 "    double  double_value;\n"
																			 "    bool    unused2;\n"
																			 "    dvec2   dvec2_value;\n"
																			 "    bvec3   unused3;\n"
																			 "    dvec3   dvec3_value;\n"
																			 "    int     unused4[3];\n"
																			 "    dvec4   dvec4_value;\n"
																			 "    bool    unused5;\n"
																			 "    bool    unused6[2];\n"
																			 "    dmat2   dmat2_value;\n"
																			 "    dmat3   dmat3_value;\n"
																			 "    bool    unused7;\n"
																			 "    dmat4   dmat4_value;\n"
																			 "    dmat2x3 dmat2x3_value;\n"
																			 "    uvec3   unused8;\n"
																			 "    dmat2x4 dmat2x4_value;\n"
																			 "    dmat3x2 dmat3x2_value;\n"
																			 "    bool    unused9;\n"
																			 "    dmat3x4 dmat3x4_value;\n"
																			 "    int     unused10;\n"
																			 "    dmat4x2 dmat4x2_value;\n"
																			 "    dmat4x3 dmat4x3_value;\n"
																			 "} "
		   << m_uniform_block_instance_name << ";\n";

	stream << "\n";
}

/** Write definitions of varyings specific for given <shader_stage> to stream
 *
 * @param stream       Output stream with source code of shader
 * @param shader_stage Shader stage
 **/
void GPUShaderFP64Test3::writeVaryingDeclarations(std::ostream& stream, shaderStage shader_stage) const
{
	static const glw::GLchar* const varying_type = "int";

	switch (shader_stage)
	{
	case FRAGMENT_SHADER:

		/* In */
		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n";
		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n";
		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n";
		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n";

		stream << "\n";

		/* Out */
		stream << "layout (location = 0) out " << varying_type << " " << m_varying_name_fs_out_fs_result << ";\n";

		break;

	case GEOMETRY_SHADER:

		/* In */
		stream << "in  " << varying_type << " " << m_varying_name_tes_gs_tcs_result << "[];\n";
		stream << "in  " << varying_type << " " << m_varying_name_tes_gs_tes_result << "[];\n";
		stream << "in  " << varying_type << " " << m_varying_name_tes_gs_vs_result << "[];\n";

		stream << "\n";

		/* Out */
		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n";
		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n";
		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n";
		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n";

		break;

	case TESS_CONTROL_SHADER:

		/* In */
		stream << "in  " << varying_type << " " << m_varying_name_vs_tcs_vs_result << "[];\n";

		stream << "\n";

		/* Out */
		stream << "out " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n";
		stream << "out " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n";

		break;

	case TESS_EVAL_SHADER:

		/* In */
		stream << "in  " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n";
		stream << "in  " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n";

		stream << "\n";

		/* Out */
		stream << "out " << varying_type << " " << m_varying_name_tes_gs_tcs_result << ";\n";
		stream << "out " << varying_type << " " << m_varying_name_tes_gs_tes_result << ";\n";
		stream << "out " << varying_type << " " << m_varying_name_tes_gs_vs_result << ";\n";

		break;

	case VERTEX_SHADER:

		/* Out */
		stream << "out " << varying_type << " " << m_varying_name_vs_tcs_vs_result << ";\n";

		break;
	}

	stream << "\n";
}

/** Write passthrough code of "input/output" varying pairs to stream
 *
 * @param stream       Output stream with source code of shader
 * @param shader_stage Shader stage
 **/
void GPUShaderFP64Test3::writeVaryingPassthrough(std::ostream& stream, shaderStage shader_stage) const
{
	switch (shader_stage)
	{
	case FRAGMENT_SHADER:
		break;

	case GEOMETRY_SHADER:

		stream << "    " << m_varying_name_gs_fs_tcs_result << " = " << m_varying_name_tes_gs_tcs_result << "[0];\n";
		stream << "    " << m_varying_name_gs_fs_tes_result << " = " << m_varying_name_tes_gs_tes_result << "[0];\n";
		stream << "    " << m_varying_name_gs_fs_vs_result << " = " << m_varying_name_tes_gs_vs_result << "[0];\n";

		break;

	case TESS_CONTROL_SHADER:

		stream << "    " << m_varying_name_tcs_tes_vs_result
			   << "[gl_InvocationID] = " << m_varying_name_vs_tcs_vs_result << "[0];\n";

		break;

	case TESS_EVAL_SHADER:

		stream << "    " << m_varying_name_tes_gs_tcs_result << " = " << m_varying_name_tcs_tes_tcs_result << "[0];\n";
		stream << "    " << m_varying_name_tes_gs_vs_result << " = " << m_varying_name_tcs_tes_vs_result << "[0];\n";

		break;

	case VERTEX_SHADER:

		break;
	}
}

/** Constructor. Sets all uniform locations to -1 and sets all
 *  values to 0.
 */
GPUShaderFP64Test4::_data::_data()
{
	memset(&uniform_double, 0, sizeof(uniform_double));
	memset(uniform_dvec2, 0, sizeof(uniform_dvec2));
	memset(uniform_dvec2_arr, 0, sizeof(uniform_dvec2_arr));
	memset(uniform_dvec3, 0, sizeof(uniform_dvec3));
	memset(uniform_dvec3_arr, 0, sizeof(uniform_dvec3_arr));
	memset(uniform_dvec4, 0, sizeof(uniform_dvec4));
	memset(uniform_dvec4_arr, 0, sizeof(uniform_dvec4_arr));

	uniform_location_double		   = -1;
	uniform_location_double_arr[0] = -1;
	uniform_location_double_arr[1] = -1;
	uniform_location_dvec2		   = -1;
	uniform_location_dvec2_arr[0]  = -1;
	uniform_location_dvec2_arr[1]  = -1;
	uniform_location_dvec3		   = -1;
	uniform_location_dvec3_arr[0]  = -1;
	uniform_location_dvec3_arr[1]  = -1;
	uniform_location_dvec4		   = -1;
	uniform_location_dvec4_arr[0]  = -1;
	uniform_location_dvec4_arr[1]  = -1;
}

/** Constructor
 *
 *  @param context Rendering context.
 */
GPUShaderFP64Test4::GPUShaderFP64Test4(deqp::Context& context)
	: TestCase(context, "state_query", "Verifies glGet*() calls, as well as \"program interface query\"-specific tools"
									   " report correct properties of & values assigned to double-precision uniforms.")
	, m_has_test_passed(true)
	, m_uniform_name_buffer(0)
	, m_cs_id(0)
	, m_fs_id(0)
	, m_gs_id(0)
	, m_po_cs_id(0)
	, m_po_noncs_id(0)
	, m_tc_id(0)
	, m_te_id(0)
	, m_vs_id(0)
{
	/* Left blank intentionally */
}

/** Deinitializes all GL objects, as well as releases all bufers, that may
 *  have beenallocated or  created during test execution.
 **/
void GPUShaderFP64Test4::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_cs_id != 0)
	{
		gl.deleteShader(m_cs_id);

		m_cs_id = 0;
	}

	if (m_fs_id != 0)
	{
		gl.deleteShader(m_fs_id);

		m_fs_id = 0;
	}

	if (m_gs_id != 0)
	{
		gl.deleteShader(m_gs_id);

		m_gs_id = 0;
	}

	if (m_po_cs_id != 0)
	{
		gl.deleteProgram(m_po_cs_id);

		m_po_cs_id = 0;
	}

	if (m_po_noncs_id != 0)
	{
		gl.deleteProgram(m_po_noncs_id);

		m_po_noncs_id = 0;
	}

	if (m_tc_id != 0)
	{
		gl.deleteShader(m_tc_id);

		m_tc_id = 0;
	}

	if (m_te_id != 0)
	{
		gl.deleteShader(m_te_id);

		m_te_id = 0;
	}

	if (m_uniform_name_buffer != DE_NULL)
	{
		delete[] m_uniform_name_buffer;

		m_uniform_name_buffer = DE_NULL;
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Generates double-precision values for all uniforms defined for all program objects
 *  used by the test.
 *
 *  This function DOES NOT use any GL API. It only calculates & stores the values
 *  in internal storage for further usage.
 */
void GPUShaderFP64Test4::generateUniformValues()
{
	_stage_data*	   stages[] = { &m_data_cs, &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
	const unsigned int n_stages = sizeof(stages) / sizeof(stages[0]);

	for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
	{
		_stage_data* stage_ptr = stages[n_stage];

		/* Iterate through all uniform components and assign them double values */
		double* double_ptrs[] = {
			&stage_ptr->uniform_structure_arrays[0].uniform_double,
			stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 0,
			stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 1,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 0,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 1,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 2,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 3,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 0,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 1,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 2,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 3,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 4,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 5,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 0,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 1,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 2,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 3,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 4,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 5,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 6,
			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 7,
			&stage_ptr->uniform_structure_arrays[1].uniform_double,
			stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 0,
			stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 1,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 0,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 1,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 2,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 3,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 0,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 1,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 2,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 3,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 4,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 5,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 0,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 1,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 2,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 3,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 4,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 5,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 6,
			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 7,
			&stage_ptr->uniforms.uniform_double,
			stage_ptr->uniforms.uniform_double_arr + 0,
			stage_ptr->uniforms.uniform_double_arr + 1,
			stage_ptr->uniforms.uniform_dvec2 + 0,
			stage_ptr->uniforms.uniform_dvec2 + 1,
			stage_ptr->uniforms.uniform_dvec2_arr + 0,
			stage_ptr->uniforms.uniform_dvec2_arr + 1,
			stage_ptr->uniforms.uniform_dvec2_arr + 2,
			stage_ptr->uniforms.uniform_dvec2_arr + 3,
			stage_ptr->uniforms.uniform_dvec3 + 0,
			stage_ptr->uniforms.uniform_dvec3 + 1,
			stage_ptr->uniforms.uniform_dvec3 + 2,
			stage_ptr->uniforms.uniform_dvec3_arr + 0,
			stage_ptr->uniforms.uniform_dvec3_arr + 1,
			stage_ptr->uniforms.uniform_dvec3_arr + 2,
			stage_ptr->uniforms.uniform_dvec3_arr + 3,
			stage_ptr->uniforms.uniform_dvec3_arr + 4,
			stage_ptr->uniforms.uniform_dvec3_arr + 5,
			stage_ptr->uniforms.uniform_dvec4 + 0,
			stage_ptr->uniforms.uniform_dvec4 + 1,
			stage_ptr->uniforms.uniform_dvec4 + 2,
			stage_ptr->uniforms.uniform_dvec4 + 3,
			stage_ptr->uniforms.uniform_dvec4_arr + 0,
			stage_ptr->uniforms.uniform_dvec4_arr + 1,
			stage_ptr->uniforms.uniform_dvec4_arr + 2,
			stage_ptr->uniforms.uniform_dvec4_arr + 3,
			stage_ptr->uniforms.uniform_dvec4_arr + 4,
			stage_ptr->uniforms.uniform_dvec4_arr + 5,
			stage_ptr->uniforms.uniform_dvec4_arr + 6,
			stage_ptr->uniforms.uniform_dvec4_arr + 7,
		};
		const unsigned int n_double_ptrs = sizeof(double_ptrs) / sizeof(double_ptrs[0]);

		for (unsigned int n_double_ptr = 0; n_double_ptr < n_double_ptrs; ++n_double_ptr)
		{
			double* double_ptr = double_ptrs[n_double_ptr];

			/* Generate the value. Use magic numbers to generate a set of double-precision
			 * floating-point numbers.
			 */
			static int seed = 16762362;

			*double_ptr = ((double)(seed % 1732)) / 125.7 * (((seed % 2) == 0) ? 1 : -1);

			seed += 751;
		} /* for (all pointers to double variables) */
	}	 /* for (all stages) */
}

/** Initializes all program & shader objects required to run the test. The function also
 *  retrieves locations of all uniforms defined by both program objects.
 **/
void GPUShaderFP64Test4::initProgramObjects()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create program & shader objects */

	/* Compute shader support and GL 4.2 required */
	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
	{
		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
	}

	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");

	/* m_cs_id is initialized only if compute shaders are supported */
	if (0 != m_cs_id)
	{
		m_po_cs_id = gl.createProgram();
	}

	m_po_noncs_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");

	/* Configure compute shader body */
	const char* cs_body = "#version 420\n"
						  "#extension GL_ARB_compute_shader          : require\n"
						  "\n"
						  "layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n"
						  "\n"
						  "layout(rgba32f) uniform image2D testImage;\n"
						  "\n"
						  "uniform double cs_double;\n"
						  "uniform dvec2  cs_dvec2;\n"
						  "uniform dvec3  cs_dvec3;\n"
						  "uniform dvec4  cs_dvec4;\n"
						  "uniform double cs_double_arr[2];\n"
						  "uniform dvec2  cs_dvec2_arr [2];\n"
						  "uniform dvec3  cs_dvec3_arr [2];\n"
						  "uniform dvec4  cs_dvec4_arr [2];\n"
						  "\n"
						  "uniform struct cs_struct\n"
						  "{\n"
						  "    double struct_double;\n"
						  "    dvec2  struct_dvec2;\n"
						  "    dvec3  struct_dvec3;\n"
						  "    dvec4  struct_dvec4;\n"
						  "} cs_array[2];\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    double tmp = cs_double                  * cs_dvec2.x                 * cs_dvec3.y       "
						  "          * cs_dvec4.z                 *\n"
						  "                 cs_double_arr[0]           * cs_dvec2_arr[0].x          * "
						  "cs_dvec3_arr[0].z          * cs_dvec4_arr[0].w          *\n"
						  "                 cs_double_arr[1]           * cs_dvec2_arr[1].x          * "
						  "cs_dvec3_arr[1].z          * cs_dvec4_arr[1].w          *\n"
						  "                 cs_array[0].struct_double  * cs_array[0].struct_dvec2.y * "
						  "cs_array[0].struct_dvec3.z * cs_array[0].struct_dvec4.w *\n"
						  "                 cs_array[1].struct_double  * cs_array[1].struct_dvec2.y * "
						  "cs_array[1].struct_dvec3.z * cs_array[1].struct_dvec4.w;\n"
						  "\n"
						  "    imageStore(testImage, ivec2(0, 0), (tmp > 1.0) ? vec4(1.0) : vec4(0.0) );\n"
						  "}\n";

	/* m_cs_id is initialized only if compute shaders are supported */
	if (0 != m_cs_id)
	{
		gl.shaderSource(m_cs_id, 1 /* count */, &cs_body, DE_NULL /* length */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
	}

	/* Configure vertex shader body */
	const char* vs_body = "#version 400\n"
						  "\n"
						  "uniform double vs_double;\n"
						  "uniform dvec2  vs_dvec2;\n"
						  "uniform dvec3  vs_dvec3;\n"
						  "uniform dvec4  vs_dvec4;\n"
						  "uniform double vs_double_arr[2];\n"
						  "uniform dvec2  vs_dvec2_arr [2];\n"
						  "uniform dvec3  vs_dvec3_arr [2];\n"
						  "uniform dvec4  vs_dvec4_arr [2];\n"
						  "\n"
						  "uniform struct vs_struct\n"
						  "{\n"
						  "    double struct_double;\n"
						  "    dvec2  struct_dvec2;\n"
						  "    dvec3  struct_dvec3;\n"
						  "    dvec4  struct_dvec4;\n"
						  "} vs_array[2];\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    if (vs_double                 * vs_dvec2.x                 * vs_dvec3.x                 "
						  "* vs_dvec4.x                 *\n"
						  "        vs_double_arr[0]          * vs_dvec2_arr[0].x          * vs_dvec3_arr[0].x          "
						  "* vs_dvec4_arr[0].x          *\n"
						  "        vs_double_arr[1]          * vs_dvec2_arr[1].x          * vs_dvec3_arr[1].x          "
						  "* vs_dvec4_arr[1].x          *\n"
						  "        vs_array[0].struct_double * vs_array[0].struct_dvec2.x * vs_array[0].struct_dvec3.x "
						  "* vs_array[0].struct_dvec4.x *\n"
						  "        vs_array[1].struct_double * vs_array[1].struct_dvec2.x * vs_array[1].struct_dvec3.x "
						  "* vs_array[1].struct_dvec4.x > 1.0)\n"
						  "    {\n"
						  "        gl_Position = vec4(0);\n"
						  "    }\n"
						  "    else\n"
						  "    {\n"
						  "        gl_Position = vec4(1);\n"
						  "    }\n"
						  "}\n";

	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	/* Configure tessellation control shader body */
	const char* tc_body = "#version 400\n"
						  "\n"
						  "uniform double tc_double;\n"
						  "uniform dvec2  tc_dvec2;\n"
						  "uniform dvec3  tc_dvec3;\n"
						  "uniform dvec4  tc_dvec4;\n"
						  "uniform double tc_double_arr[2];\n"
						  "uniform dvec2  tc_dvec2_arr [2];\n"
						  "uniform dvec3  tc_dvec3_arr [2];\n"
						  "uniform dvec4  tc_dvec4_arr [2];\n"
						  "\n"
						  "uniform struct tc_struct\n"
						  "{\n"
						  "    double struct_double;\n"
						  "    dvec2  struct_dvec2;\n"
						  "    dvec3  struct_dvec3;\n"
						  "    dvec4  struct_dvec4;\n"
						  "} tc_array[2];\n"
						  "\n"
						  "layout(vertices = 4) out;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    gl_TessLevelOuter[0] = (tc_double        > 1.0) ? 2.0 : 3.0;\n"
						  "    gl_TessLevelOuter[1] = (tc_dvec2.x       > 1.0) ? 3.0 : 4.0;\n"
						  "    gl_TessLevelOuter[2] = (tc_dvec3.x       > 1.0) ? 4.0 : 5.0;\n"
						  "    gl_TessLevelOuter[3] = (tc_dvec4.x       > 1.0) ? 5.0 : 6.0;\n"
						  "    gl_TessLevelInner[0] = (tc_double_arr[0] > 1.0) ? 6.0 : 7.0;\n"
						  "    gl_TessLevelInner[1] = (tc_double_arr[1] > 1.0) ? 7.0 : 8.0;\n"
						  "\n"
						  "    if (tc_dvec2_arr[0].y          * tc_dvec2_arr[1].y          *\n"
						  "        tc_dvec3_arr[0].z          * tc_dvec3_arr[1].z          *\n"
						  "        tc_dvec4_arr[0].z          * tc_dvec4_arr[1].z          *\n"
						  "        tc_array[0].struct_double  * tc_array[0].struct_dvec2.x * \n"
						  "        tc_array[0].struct_dvec3.y * tc_array[0].struct_dvec4.z * \n"
						  "        tc_array[1].struct_double  * tc_array[1].struct_dvec2.x * \n"
						  "        tc_array[1].struct_dvec3.y * tc_array[1].struct_dvec4.z > 0.0)\n"
						  "    {\n"
						  "        gl_TessLevelInner[1] = 3.0;\n"
						  "    }\n"
						  "}\n";

	gl.shaderSource(m_tc_id, 1 /* count */, &tc_body, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	/* Configure tessellation evaluation shader body */
	const char* te_body = "#version 400\n"
						  "\n"
						  "uniform double te_double;\n"
						  "uniform dvec2  te_dvec2;\n"
						  "uniform dvec3  te_dvec3;\n"
						  "uniform dvec4  te_dvec4;\n"
						  "uniform double te_double_arr[2];\n"
						  "uniform dvec2  te_dvec2_arr [2];\n"
						  "uniform dvec3  te_dvec3_arr [2];\n"
						  "uniform dvec4  te_dvec4_arr [2];\n"
						  "\n"
						  "uniform struct te_struct\n"
						  "{\n"
						  "    double struct_double;\n"
						  "    dvec2  struct_dvec2;\n"
						  "    dvec3  struct_dvec3;\n"
						  "    dvec4  struct_dvec4;\n"
						  "} te_array[2];\n"
						  "\n"
						  "layout(triangles) in;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    if (te_double                 * te_dvec2.x                 * te_dvec3.x                 "
						  "* te_dvec4.x                 *\n"
						  "        te_double_arr[0]          * te_dvec2_arr[0].x          * te_dvec3_arr[0].x          "
						  "* te_dvec4_arr[0].x          *\n"
						  "        te_double_arr[1]          * te_dvec2_arr[1].x          * te_dvec3_arr[1].x          "
						  "* te_dvec4_arr[1].x          *\n"
						  "        te_array[0].struct_double * te_array[0].struct_dvec2.x * te_array[0].struct_dvec3.x "
						  "* te_array[0].struct_dvec4.x *\n"
						  "        te_array[1].struct_double * te_array[1].struct_dvec2.x * te_array[1].struct_dvec3.x "
						  "* te_array[1].struct_dvec4.x > 1.0)\n"
						  "    {\n"
						  "        gl_Position = gl_in[0].gl_Position;\n"
						  "    }\n"
						  "    else\n"
						  "    {\n"
						  "        gl_Position = gl_in[0].gl_Position + vec4(1);\n"
						  "    }\n"
						  "}\n";

	gl.shaderSource(m_te_id, 1 /* count */, &te_body, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	/* Configure geometry shader body */
	const char* gs_body = "#version 400\n"
						  "\n"
						  "uniform double gs_double;\n"
						  "uniform dvec2  gs_dvec2;\n"
						  "uniform dvec3  gs_dvec3;\n"
						  "uniform dvec4  gs_dvec4;\n"
						  "uniform double gs_double_arr[2];\n"
						  "uniform dvec2  gs_dvec2_arr [2];\n"
						  "uniform dvec3  gs_dvec3_arr [2];\n"
						  "uniform dvec4  gs_dvec4_arr [2];\n"
						  "\n"
						  "uniform struct gs_struct\n"
						  "{\n"
						  "    double struct_double;\n"
						  "    dvec2  struct_dvec2;\n"
						  "    dvec3  struct_dvec3;\n"
						  "    dvec4  struct_dvec4;\n"
						  "} gs_array[2];\n"
						  "\n"
						  "layout (points)                   in;\n"
						  "layout (points, max_vertices = 1) out;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    if (gs_double                 * gs_dvec2.x                 * gs_dvec3.x                 "
						  "* gs_dvec4.x        *\n"
						  "        gs_double_arr[0]          * gs_dvec2_arr[0].x          * gs_dvec3_arr[0].x          "
						  "* gs_dvec4_arr[0].x *\n"
						  "        gs_double_arr[1]          * gs_dvec2_arr[1].x          * gs_dvec3_arr[1].x          "
						  "* gs_dvec4_arr[1].x *\n"
						  "        gs_array[0].struct_double * gs_array[0].struct_dvec2.x * gs_array[0].struct_dvec3.x "
						  "* gs_array[0].struct_dvec4.x *\n"
						  "        gs_array[1].struct_double * gs_array[1].struct_dvec2.x * gs_array[1].struct_dvec3.x "
						  "* gs_array[1].struct_dvec4.x > 1.0)\n"
						  "    {\n"
						  "        gl_Position = gl_in[0].gl_Position;\n"
						  "    }\n"
						  "    else\n"
						  "    {\n"
						  "        gl_Position = gl_in[0].gl_Position + vec4(1);\n"
						  "    }\n"
						  "\n"
						  "    EmitVertex();\n"
						  "}\n";

	gl.shaderSource(m_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	/* Configure fragment shader body */
	const char* fs_body = "#version 400\n"
						  "\n"
						  "uniform double fs_double;\n"
						  "uniform dvec2  fs_dvec2;\n"
						  "uniform dvec3  fs_dvec3;\n"
						  "uniform dvec4  fs_dvec4;\n"
						  "uniform double fs_double_arr[2];\n"
						  "uniform dvec2  fs_dvec2_arr [2];\n"
						  "uniform dvec3  fs_dvec3_arr [2];\n"
						  "uniform dvec4  fs_dvec4_arr [2];\n"
						  "\n"
						  "uniform struct fs_struct\n"
						  "{\n"
						  "    double struct_double;\n"
						  "    dvec2  struct_dvec2;\n"
						  "    dvec3  struct_dvec3;\n"
						  "    dvec4  struct_dvec4;\n"
						  "} fs_array[2];\n"
						  "\n"
						  "out vec4 result;\n"
						  "\n"
						  "void main()\n"
						  "{\n"
						  "    if (fs_double                 * fs_dvec2.x                 * fs_dvec3.x                 "
						  "* fs_dvec4.x        *\n"
						  "        fs_double_arr[0]          * fs_dvec2_arr[0].x          * fs_dvec3_arr[0].x          "
						  "* fs_dvec4_arr[0].x *\n"
						  "        fs_double_arr[1]          * fs_dvec2_arr[1].x          * fs_dvec3_arr[1].x          "
						  "* fs_dvec4_arr[1].x *\n"
						  "        fs_array[0].struct_double * fs_array[0].struct_dvec2.x * fs_array[0].struct_dvec3.x "
						  "* fs_array[0].struct_dvec4.x *\n"
						  "        fs_array[1].struct_double * fs_array[1].struct_dvec2.x * fs_array[1].struct_dvec3.x "
						  "* fs_array[1].struct_dvec4.x > 1.0)\n"
						  "    {\n"
						  "        result = vec4(0.0);\n"
						  "    }\n"
						  "    else\n"
						  "    {\n"
						  "        result = vec4(1.0);\n"
						  "    }\n"
						  "}\n";

	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");

	/* Compile the shaders */
	const glw::GLuint  shaders[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
	const unsigned int n_shaders = sizeof(shaders) / sizeof(shaders[0]);

	for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
	{
		glw::GLint  compile_status = GL_FALSE;
		glw::GLuint so_id		   = shaders[n_shader];

		/* Skip compute shader if not supported */
		if (0 == so_id)
		{
			continue;
		}

		gl.compileShader(so_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");

		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");

		if (compile_status != GL_TRUE)
		{
			TCU_FAIL("Shader compilation failed");
		}

		if (so_id == m_cs_id)
		{
			gl.attachShader(m_po_cs_id, so_id);
		}
		else
		{
			gl.attachShader(m_po_noncs_id, so_id);
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
	} /* for (all shaders) */

	/* Link the program */
	const glw::GLuint  programs[]  = { m_po_cs_id, m_po_noncs_id };
	const unsigned int n_programs  = sizeof(programs) / sizeof(programs[0]);
	glw::GLint		   link_status = GL_FALSE;

	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
	{
		glw::GLuint po_id = programs[n_program];

		/* Skip compute shader program if not supported */
		if (0 == po_id)
		{
			continue;
		}

		gl.linkProgram(po_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

		gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");

		if (link_status != GL_TRUE)
		{
			TCU_FAIL("Program linking failed");
		}
	} /* for (both program objects) */

	/* Retrieve uniform locations */
	_stage_data*			  cs_stage_data[]		= { &m_data_cs };
	static const char*		  cs_uniform_prefixes[] = { "cs_" };
	static const unsigned int n_cs_uniform_prefixes = sizeof(cs_uniform_prefixes) / sizeof(cs_uniform_prefixes[0]);

	_stage_data*			  noncs_stage_data[]	   = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
	static const char*		  noncs_uniform_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" };
	static const unsigned int n_noncs_uniform_prefixes =
		sizeof(noncs_uniform_prefixes) / sizeof(noncs_uniform_prefixes[0]);

	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
	{
		unsigned int  n_uniform_prefixes = DE_NULL;
		glw::GLuint   po_id				 = programs[n_program];
		_stage_data** stages_data		 = DE_NULL;
		const char**  uniform_prefixes   = DE_NULL;

		if (n_program == 0)
		{
			stages_data		   = cs_stage_data;
			uniform_prefixes   = cs_uniform_prefixes;
			n_uniform_prefixes = n_cs_uniform_prefixes;
		}
		else
		{
			stages_data		   = noncs_stage_data;
			uniform_prefixes   = noncs_uniform_prefixes;
			n_uniform_prefixes = n_noncs_uniform_prefixes;
		}

		/* Skip compute shader program if not supported */
		if (0 == po_id)
		{
			continue;
		}

		/* Uniform names used by the test program consist of a prefix (different for each
		 * shader stage) and a common part.
		 */
		for (unsigned int n_uniform_prefix = 0; n_uniform_prefix < n_uniform_prefixes; ++n_uniform_prefix)
		{
			_stage_data* stage_data				  = stages_data[n_uniform_prefix];
			std::string  uniform_prefix			  = std::string(uniform_prefixes[n_uniform_prefix]);
			std::string  uniform_double_name	  = uniform_prefix + "double";
			std::string  uniform_double_arr0_name = uniform_prefix + "double_arr[0]";
			std::string  uniform_double_arr1_name = uniform_prefix + "double_arr[1]";
			std::string  uniform_dvec2_name		  = uniform_prefix + "dvec2";
			std::string  uniform_dvec2_arr0_name  = uniform_prefix + "dvec2_arr[0]";
			std::string  uniform_dvec2_arr1_name  = uniform_prefix + "dvec2_arr[1]";
			std::string  uniform_dvec3_name		  = uniform_prefix + "dvec3";
			std::string  uniform_dvec3_arr0_name  = uniform_prefix + "dvec3_arr[0]";
			std::string  uniform_dvec3_arr1_name  = uniform_prefix + "dvec3_arr[1]";
			std::string  uniform_dvec4_name		  = uniform_prefix + "dvec4";
			std::string  uniform_dvec4_arr0_name  = uniform_prefix + "dvec4_arr[0]";
			std::string  uniform_dvec4_arr1_name  = uniform_prefix + "dvec4_arr[1]";
			std::string  uniform_arr0_double_name = uniform_prefix + "array[0].struct_double";
			std::string  uniform_arr0_dvec2_name  = uniform_prefix + "array[0].struct_dvec2";
			std::string  uniform_arr0_dvec3_name  = uniform_prefix + "array[0].struct_dvec3";
			std::string  uniform_arr0_dvec4_name  = uniform_prefix + "array[0].struct_dvec4";
			std::string  uniform_arr1_double_name = uniform_prefix + "array[1].struct_double";
			std::string  uniform_arr1_dvec2_name  = uniform_prefix + "array[1].struct_dvec2";
			std::string  uniform_arr1_dvec3_name  = uniform_prefix + "array[1].struct_dvec3";
			std::string  uniform_arr1_dvec4_name  = uniform_prefix + "array[1].struct_dvec4";

			/* Retrieve uniform locations */
			stage_data->uniforms.uniform_location_double = gl.getUniformLocation(po_id, uniform_double_name.c_str());
			stage_data->uniforms.uniform_location_double_arr[0] =
				gl.getUniformLocation(po_id, uniform_double_arr0_name.c_str());
			stage_data->uniforms.uniform_location_double_arr[1] =
				gl.getUniformLocation(po_id, uniform_double_arr1_name.c_str());
			stage_data->uniforms.uniform_location_dvec2 = gl.getUniformLocation(po_id, uniform_dvec2_name.c_str());
			stage_data->uniforms.uniform_location_dvec2_arr[0] =
				gl.getUniformLocation(po_id, uniform_dvec2_arr0_name.c_str());
			stage_data->uniforms.uniform_location_dvec2_arr[1] =
				gl.getUniformLocation(po_id, uniform_dvec2_arr1_name.c_str());
			stage_data->uniforms.uniform_location_dvec3 = gl.getUniformLocation(po_id, uniform_dvec3_name.c_str());
			stage_data->uniforms.uniform_location_dvec3_arr[0] =
				gl.getUniformLocation(po_id, uniform_dvec3_arr0_name.c_str());
			stage_data->uniforms.uniform_location_dvec3_arr[1] =
				gl.getUniformLocation(po_id, uniform_dvec3_arr1_name.c_str());
			stage_data->uniforms.uniform_location_dvec4 = gl.getUniformLocation(po_id, uniform_dvec4_name.c_str());
			stage_data->uniforms.uniform_location_dvec4_arr[0] =
				gl.getUniformLocation(po_id, uniform_dvec4_arr0_name.c_str());
			stage_data->uniforms.uniform_location_dvec4_arr[1] =
				gl.getUniformLocation(po_id, uniform_dvec4_arr1_name.c_str());
			stage_data->uniform_structure_arrays[0].uniform_location_double =
				gl.getUniformLocation(po_id, uniform_arr0_double_name.c_str());
			stage_data->uniform_structure_arrays[0].uniform_location_dvec2 =
				gl.getUniformLocation(po_id, uniform_arr0_dvec2_name.c_str());
			stage_data->uniform_structure_arrays[0].uniform_location_dvec3 =
				gl.getUniformLocation(po_id, uniform_arr0_dvec3_name.c_str());
			stage_data->uniform_structure_arrays[0].uniform_location_dvec4 =
				gl.getUniformLocation(po_id, uniform_arr0_dvec4_name.c_str());
			stage_data->uniform_structure_arrays[1].uniform_location_double =
				gl.getUniformLocation(po_id, uniform_arr1_double_name.c_str());
			stage_data->uniform_structure_arrays[1].uniform_location_dvec2 =
				gl.getUniformLocation(po_id, uniform_arr1_dvec2_name.c_str());
			stage_data->uniform_structure_arrays[1].uniform_location_dvec3 =
				gl.getUniformLocation(po_id, uniform_arr1_dvec3_name.c_str());
			stage_data->uniform_structure_arrays[1].uniform_location_dvec4 =
				gl.getUniformLocation(po_id, uniform_arr1_dvec4_name.c_str());
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");

			if (stage_data->uniforms.uniform_location_double == -1 ||
				stage_data->uniforms.uniform_location_double_arr[0] == -1 ||
				stage_data->uniforms.uniform_location_double_arr[1] == -1 ||
				stage_data->uniforms.uniform_location_dvec2 == -1 ||
				stage_data->uniforms.uniform_location_dvec2_arr[0] == -1 ||
				stage_data->uniforms.uniform_location_dvec2_arr[1] == -1 ||
				stage_data->uniforms.uniform_location_dvec3 == -1 ||
				stage_data->uniforms.uniform_location_dvec3_arr[0] == -1 ||
				stage_data->uniforms.uniform_location_dvec3_arr[1] == -1 ||
				stage_data->uniforms.uniform_location_dvec4 == -1 ||
				stage_data->uniforms.uniform_location_dvec4_arr[0] == -1 ||
				stage_data->uniforms.uniform_location_dvec4_arr[1] == -1 ||
				stage_data->uniform_structure_arrays[0].uniform_location_double == -1 ||
				stage_data->uniform_structure_arrays[0].uniform_location_dvec2 == -1 ||
				stage_data->uniform_structure_arrays[0].uniform_location_dvec3 == -1 ||
				stage_data->uniform_structure_arrays[0].uniform_location_dvec4 == -1 ||
				stage_data->uniform_structure_arrays[1].uniform_location_double == -1 ||
				stage_data->uniform_structure_arrays[1].uniform_location_dvec2 == -1 ||
				stage_data->uniform_structure_arrays[1].uniform_location_dvec3 == -1 ||
				stage_data->uniform_structure_arrays[1].uniform_location_dvec4 == -1)
			{
				TCU_FAIL("At least one uniform is considered inactive which is invalid.");
			}

			/* Make sure locations of subsequent items in array uniforms are correct */
			if (stage_data->uniforms.uniform_location_double_arr[1] !=
					(stage_data->uniforms.uniform_location_double_arr[0] + 1) ||
				stage_data->uniforms.uniform_location_dvec2_arr[1] !=
					(stage_data->uniforms.uniform_location_dvec2_arr[0] + 1) ||
				stage_data->uniforms.uniform_location_dvec3_arr[1] !=
					(stage_data->uniforms.uniform_location_dvec3_arr[0] + 1) ||
				stage_data->uniforms.uniform_location_dvec4_arr[1] !=
					(stage_data->uniforms.uniform_location_dvec4_arr[0] + 1))
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Uniform locations:"
															   " double_arr[0]:"
								   << stage_data->uniforms.uniform_location_double_arr[0]
								   << " double_arr[1]:" << stage_data->uniforms.uniform_location_double_arr[1]
								   << " dvec2_arr[0]:" << stage_data->uniforms.uniform_location_dvec2_arr[0]
								   << " dvec2_arr[1]:" << stage_data->uniforms.uniform_location_dvec2_arr[1]
								   << " dvec3_arr[0]:" << stage_data->uniforms.uniform_location_dvec3_arr[0]
								   << " dvec3_arr[1]:" << stage_data->uniforms.uniform_location_dvec3_arr[1]
								   << " dvec4_arr[0]:" << stage_data->uniforms.uniform_location_dvec4_arr[0]
								   << " dvec4_arr[1]:" << stage_data->uniforms.uniform_location_dvec4_arr[1]
								   << tcu::TestLog::EndMessage;

				TCU_FAIL("Double-precision uniform array item locations are invalid.");
			}
		} /* for (all uniform prefixes) */
	}	 /* for (both program objects) */
}

/** Initializes all objects required to run the test. */
void GPUShaderFP64Test4::initTest()
{
	initProgramObjects();

	generateUniformValues();
	initUniformValues();
}

/** Assigns values generated by generateUniformValues() to uniforms defined by
 *  both program objects.
 **/
void GPUShaderFP64Test4::initUniformValues()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Iterate through all programs */
	_stage_data*	   cs_stages[]	= { &m_data_cs };
	_stage_data*	   noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
	const unsigned int n_cs_stages	= sizeof(cs_stages) / sizeof(cs_stages[0]);
	const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);

	const glw::GLuint  programs[] = { m_po_cs_id, m_po_noncs_id };
	const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);

	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
	{
		glw::GLuint   po_id		 = programs[n_program];
		unsigned int  n_stages   = 0;
		_stage_data** stage_data = DE_NULL;

		if (po_id == m_po_cs_id)
		{
			n_stages   = n_cs_stages;
			stage_data = cs_stages;
		}
		else
		{
			n_stages   = n_noncs_stages;
			stage_data = noncs_stages;
		}

		/* Skip compute shader program if not supported */
		if (0 == po_id)
		{
			continue;
		}

		gl.useProgram(po_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

		for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
		{
			/* Iterate through all uniforms */
			_stage_data* stage_ptr = stage_data[n_stage];

			gl.uniform1d(stage_ptr->uniforms.uniform_location_double, stage_ptr->uniforms.uniform_double);
			gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[0], stage_ptr->uniforms.uniform_double_arr[0]);
			gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[1], stage_ptr->uniforms.uniform_double_arr[1]);
			gl.uniform1d(stage_ptr->uniform_structure_arrays[0].uniform_location_double,
						 stage_ptr->uniform_structure_arrays[0].uniform_double);
			gl.uniform1d(stage_ptr->uniform_structure_arrays[1].uniform_location_double,
						 stage_ptr->uniform_structure_arrays[1].uniform_double);
			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform1d() call(s) failed.");

			gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2, 1 /* count */, stage_ptr->uniforms.uniform_dvec2);
			gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[0], 1 /* count */,
						  stage_ptr->uniforms.uniform_dvec2_arr + 0);
			gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[1], 1 /* count */,
						  stage_ptr->uniforms.uniform_dvec2_arr + 2);
			gl.uniform2dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2, 1 /* count */,
						  stage_ptr->uniform_structure_arrays[0].uniform_dvec2);
			gl.uniform2dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2, 1 /* count */,
						  stage_ptr->uniform_structure_arrays[1].uniform_dvec2);
			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform2dv() call(s) failed.");

			gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3, 1 /* count */, stage_ptr->uniforms.uniform_dvec3);
			gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[0], 1 /* count */,
						  stage_ptr->uniforms.uniform_dvec3_arr + 0);
			gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[1], 1 /* count */,
						  stage_ptr->uniforms.uniform_dvec3_arr + 3);
			gl.uniform3dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3, 1 /* count */,
						  stage_ptr->uniform_structure_arrays[0].uniform_dvec3);
			gl.uniform3dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3, 1 /* count */,
						  stage_ptr->uniform_structure_arrays[1].uniform_dvec3);
			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform3dv() call(s) failed.");

			gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4, 1 /* count */, stage_ptr->uniforms.uniform_dvec4);
			gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[0], 1 /* count */,
						  stage_ptr->uniforms.uniform_dvec4_arr + 0);
			gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[1], 1 /* count */,
						  stage_ptr->uniforms.uniform_dvec4_arr + 4);
			gl.uniform4dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4, 1 /* count */,
						  stage_ptr->uniform_structure_arrays[0].uniform_dvec4);
			gl.uniform4dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4, 1 /* count */,
						  stage_ptr->uniform_structure_arrays[1].uniform_dvec4);
			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform4dv() call(s) failed.");
		} /* for (all shader stages) */
	}	 /* for (both program objects) */
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test4::iterate()
{
	/* This test does not verify GL_ARB_gpu_shader_fp64 support on purpose */

	/* Initialize all objects required to run the test */
	initTest();

	/* Verify the implementation reports correct values for all stages we've configured */
	m_has_test_passed &= verifyUniformValues();

	/* Is this also the case when "program interface query" mechanism is used? */
	if (m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query"))
	{
		m_has_test_passed &= verifyProgramInterfaceQuerySupport();
	}

	/* We're done */
	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Verifies that:
 *
 *  a) glGetProgramResourceIndex()
 *  b) glGetProgramResourceiv()
 *  c) glGetProgramResourceName()
 *
 *  functions return correct values for double-precision uniforms.
 *
 *  @return true if the verification was passed, false otherwise.
 */
bool GPUShaderFP64Test4::verifyProgramInterfaceQuerySupport()
{
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	/* Iterate through all programs */
	const char*		   cs_prefixes[]	= { "cs_" };
	_stage_data*	   cs_stages[]		= { &m_data_cs };
	const char*		   noncs_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" };
	_stage_data*	   noncs_stages[]   = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
	const unsigned int n_cs_stages		= sizeof(cs_stages) / sizeof(cs_stages[0]);
	const unsigned int n_noncs_stages   = sizeof(noncs_stages) / sizeof(noncs_stages[0]);

	const glw::GLuint  programs[] = { m_po_cs_id, m_po_noncs_id };
	const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);

	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
	{
		glw::GLuint   po_id			 = programs[n_program];
		unsigned int  n_stages		 = 0;
		const char**  stage_prefixes = DE_NULL;
		_stage_data** stage_data	 = DE_NULL;

		if (po_id == m_po_cs_id)
		{
			n_stages	   = n_cs_stages;
			stage_data	 = cs_stages;
			stage_prefixes = cs_prefixes;
		}
		else
		{
			n_stages	   = n_noncs_stages;
			stage_data	 = noncs_stages;
			stage_prefixes = noncs_prefixes;
		}

		/* Skip compute shader program if not supported */
		if (0 == po_id)
		{
			continue;
		}

		/* Determine maximum uniform name length */
		glw::GLint max_uniform_name_length = 0;

		gl.getProgramInterfaceiv(po_id, GL_UNIFORM, GL_MAX_NAME_LENGTH, &max_uniform_name_length);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInterfaceiv() call failed.");

		/* Allocate a buffer we will use to hold uniform names */
		m_uniform_name_buffer = new char[max_uniform_name_length];

		for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
		{
			/* Iterate through all uniforms */
			_stage_data* stage_ptr	= stage_data[n_stage];
			const char*  stage_prefix = stage_prefixes[n_stage];

			/* Construct an array that will be used to run the test in an automated manner */
			_program_interface_query_test_item uniforms[] = {
				/* array size */ /* name */ /* type */ /* location */
				{ 1, "double", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double },
				{ 2, "double_arr[0]", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double_arr[0] },
				{ 1, "dvec2", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2 },
				{ 2, "dvec2_arr[0]", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2_arr[0] },
				{ 1, "dvec3", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3 },
				{ 2, "dvec3_arr[0]", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3_arr[0] },
				{ 1, "dvec4", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4 },
				{ 2, "dvec4_arr[0]", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4_arr[0] },
				{ 1, "array[0].struct_double", GL_DOUBLE,
				  stage_ptr->uniform_structure_arrays->uniform_location_double },
				{ 1, "array[0].struct_dvec2", GL_DOUBLE_VEC2,
				  stage_ptr->uniform_structure_arrays->uniform_location_dvec2 },
				{ 1, "array[0].struct_dvec3", GL_DOUBLE_VEC3,
				  stage_ptr->uniform_structure_arrays->uniform_location_dvec3 },
				{ 1, "array[0].struct_dvec4", GL_DOUBLE_VEC4,
				  stage_ptr->uniform_structure_arrays->uniform_location_dvec4 },
				{ 1, "array[1].struct_double", GL_DOUBLE,
				  stage_ptr->uniform_structure_arrays->uniform_location_double },
				{ 1, "array[1].struct_dvec2", GL_DOUBLE_VEC2,
				  stage_ptr->uniform_structure_arrays->uniform_location_dvec2 },
				{ 1, "array[1].struct_dvec3", GL_DOUBLE_VEC3,
				  stage_ptr->uniform_structure_arrays->uniform_location_dvec3 },
				{ 1, "array[1].struct_dvec4", GL_DOUBLE_VEC4,
				  stage_ptr->uniform_structure_arrays->uniform_location_dvec4 },
			};
			const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]);

			/* Prefix the names with stage-specific string */
			for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
			{
				_program_interface_query_test_item& current_item = uniforms[n_uniform];

				current_item.name = std::string(stage_prefix) + current_item.name;
			} /* for (all uniform descriptors) */

			const glw::GLenum  properties[] = { GL_ARRAY_SIZE, GL_TYPE };
			const unsigned int n_properties = sizeof(properties) / sizeof(properties[0]);

			for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
			{
				_program_interface_query_test_item& current_item		  = uniforms[n_uniform];
				glw::GLint							n_written_items		  = 0;
				glw::GLint							retrieved_array_size  = 0;
				glw::GLint							retrieved_name_length = 0;
				glw::GLenum							retrieved_type		  = GL_NONE;
				glw::GLint							temp_buffer[2]		  = { 0, GL_NONE };

				/* Retrieve index of the iteration-specific uniform */
				glw::GLuint resource_index = gl.getProgramResourceIndex(po_id, GL_UNIFORM, current_item.name.c_str());
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() call failed.");

				/* Make sure glGetProgramResourceName() returns correct values */
				memset(m_uniform_name_buffer, 0, max_uniform_name_length);

				gl.getProgramResourceName(po_id, GL_UNIFORM, /* interface */
										  resource_index, max_uniform_name_length, &retrieved_name_length,
										  m_uniform_name_buffer);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName() call failed.");

				if (current_item.name.length() != (glw::GLuint)retrieved_name_length ||
					memcmp(m_uniform_name_buffer, current_item.name.c_str(), retrieved_name_length) != 0)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid uniform name was reported at index ["
									   << resource_index << "]"
															": expected:["
									   << current_item.name << "]"
															   ", reported:["
									   << m_uniform_name_buffer << "]" << tcu::TestLog::EndMessage;

					result = false;
					continue;
				}

				/* Make sure glGetProgramResourceiv() returns correct values for GL_TYPE and GL_ARRAY_SIZE queries */
				gl.getProgramResourceiv(po_id, GL_UNIFORM, /* interface */
										resource_index, n_properties, properties,
										sizeof(temp_buffer) / sizeof(temp_buffer[0]), &n_written_items, temp_buffer);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv() call failed.");

				if (n_written_items != n_properties)
				{
					TCU_FAIL("Invalid amount of items were reported by glGetProgramResourceiv() call.");
				}

				/* For clarity, copy the retrieved values to separate variables */
				retrieved_array_size = temp_buffer[0];
				retrieved_type		 = temp_buffer[1];

				/* Verify the values */
				if (retrieved_array_size != current_item.expected_array_size)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid array size reported for uniform ["
									   << current_item.name << "]"
									   << ": expected:[" << current_item.expected_array_size << "]"
																								", reported:["
									   << retrieved_array_size << "]" << tcu::TestLog::EndMessage;

					result = false;
				}

				if (retrieved_type != current_item.expected_type)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid type reported for uniform ["
									   << current_item.name << "]"
									   << ": expected:[" << current_item.expected_type << "]"
																						  ", reported:["
									   << retrieved_type << "]" << tcu::TestLog::EndMessage;

					result = false;
				}
			} /* for (all uniforms) */
		}	 /* for (all shader stages) */

		/* We're now OK to release the buffer we used to hold uniform names for
		 * the program */
		if (m_uniform_name_buffer != DE_NULL)
		{
			delete[] m_uniform_name_buffer;

			m_uniform_name_buffer = DE_NULL;
		}
	} /* for (both program objects) */

	return result;
}

/** Verifies glGetUniform*() calls return correct values assigned to
 *  double-precision uniforms.
 *
 *  @return true if all values reported by OpenGL were found to be correct,
 *          false otherwise.
 **/
bool GPUShaderFP64Test4::verifyUniformValues()
{
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	/* Iterate through all programs */
	_stage_data*	   cs_stages[]	= { &m_data_cs };
	_stage_data*	   noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
	const unsigned int n_cs_stages	= sizeof(cs_stages) / sizeof(cs_stages[0]);
	const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);

	const glw::GLuint programs[] = {
		m_po_noncs_id, m_po_cs_id,
	};
	const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);

	/* Set up rounding for the tests */
	deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN);

	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
	{
		glw::GLuint   po_id		 = programs[n_program];
		unsigned int  n_stages   = 0;
		_stage_data** stage_data = DE_NULL;

		if (po_id == m_po_cs_id)
		{
			n_stages   = n_cs_stages;
			stage_data = cs_stages;
		}
		else
		{
			n_stages   = n_noncs_stages;
			stage_data = noncs_stages;
		}

		/* Skip compute shader program if not supported */
		if (0 == po_id)
		{
			continue;
		}

		for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
		{
			/* Iterate through all uniforms */
			_stage_data* stage_ptr = stage_data[n_stage];

			/* Set up arrays that we will guide the automated testing */
			const uniform_value_pair double_uniforms[] = {
				uniform_value_pair(stage_ptr->uniforms.uniform_location_double, &stage_ptr->uniforms.uniform_double),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[0],
								   stage_ptr->uniforms.uniform_double_arr + 0),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[1],
								   stage_ptr->uniforms.uniform_double_arr + 1),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_double,
								   &stage_ptr->uniform_structure_arrays[0].uniform_double),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_double,
								   &stage_ptr->uniform_structure_arrays[1].uniform_double)
			};
			const uniform_value_pair dvec2_uniforms[] = {
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2, stage_ptr->uniforms.uniform_dvec2),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[0],
								   stage_ptr->uniforms.uniform_dvec2_arr + 0),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[1],
								   stage_ptr->uniforms.uniform_dvec2_arr + 2),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2,
								   stage_ptr->uniform_structure_arrays[0].uniform_dvec2),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2,
								   stage_ptr->uniform_structure_arrays[1].uniform_dvec2)
			};
			const uniform_value_pair dvec3_uniforms[] = {
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3, stage_ptr->uniforms.uniform_dvec3),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[0],
								   stage_ptr->uniforms.uniform_dvec3_arr + 0),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[1],
								   stage_ptr->uniforms.uniform_dvec3_arr + 3),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3,
								   stage_ptr->uniform_structure_arrays[0].uniform_dvec3),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3,
								   stage_ptr->uniform_structure_arrays[1].uniform_dvec3)
			};
			const uniform_value_pair dvec4_uniforms[] = {
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4, stage_ptr->uniforms.uniform_dvec4),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[0],
								   stage_ptr->uniforms.uniform_dvec4_arr + 0),
				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[1],
								   stage_ptr->uniforms.uniform_dvec4_arr + 4),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4,
								   stage_ptr->uniform_structure_arrays[0].uniform_dvec4),
				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4,
								   stage_ptr->uniform_structure_arrays[1].uniform_dvec4)
			};

			/* Iterate over all uniforms and verify the values reported by the API */
			double		 returned_double_data[4];
			float		 returned_float_data[4];
			int			 returned_int_data[4];
			unsigned int returned_uint_data[4];

			for (unsigned int n_type = 0; n_type < 4 /* double/dvec2/dvec3/dvec4 */; ++n_type)
			{
				const uniform_value_pair* current_uv_pairs  = NULL;
				const unsigned int		  n_components_used = n_type + 1; /* n_type=0: double, n_type=1: dvec2, etc.. */
				unsigned int			  n_pairs			= 0;

				switch (n_type)
				{
				case 0: /* double */
				{
					current_uv_pairs = double_uniforms;
					n_pairs			 = sizeof(double_uniforms) / sizeof(double_uniforms[0]);

					break;
				}

				case 1: /* dvec2 */
				{
					current_uv_pairs = dvec2_uniforms;
					n_pairs			 = sizeof(dvec2_uniforms) / sizeof(dvec2_uniforms[0]);

					break;
				}

				case 2: /* dvec3 */
				{
					current_uv_pairs = dvec3_uniforms;
					n_pairs			 = sizeof(dvec3_uniforms) / sizeof(dvec3_uniforms[0]);

					break;
				}

				case 3: /* dvec4 */
				{
					current_uv_pairs = dvec4_uniforms;
					n_pairs			 = sizeof(dvec4_uniforms) / sizeof(dvec4_uniforms[0]);

					break;
				}

				default:
				{
					TCU_FAIL("Invalid type index requested");
				}
				} /* switch (n_type) */

				for (unsigned int n_pair = 0; n_pair < n_pairs; ++n_pair)
				{
					const uniform_value_pair& current_uv_pair  = current_uv_pairs[n_pair];
					glw::GLint				  uniform_location = current_uv_pair.first;
					const double*			  uniform_value	= current_uv_pair.second;

					/* Retrieve the values from the GL implementation*/
					gl.getUniformdv(po_id, uniform_location, returned_double_data);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformdv() call failed.");

					gl.getUniformfv(po_id, uniform_location, returned_float_data);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformfv() call failed.");

					gl.getUniformiv(po_id, uniform_location, returned_int_data);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformiv() call failed.");

					gl.getUniformuiv(po_id, uniform_location, returned_uint_data);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformuiv() call failed.");

					/* Make sure the values reported match the reference values */
					bool		can_continue = true;
					const float epsilon		 = 1e-5f;

					for (unsigned int n_component = 0; n_component < n_components_used && can_continue; ++n_component)
					{
						if (de::abs(returned_double_data[n_component] - uniform_value[n_component]) > epsilon)
						{
							m_testCtx.getLog()
								<< tcu::TestLog::Message
								<< "Invalid uniform value reported by glGetUniformdv() for uniform location ["
								<< uniform_location << "]"
													   " and component ["
								<< n_component << "]"
												  ": retrieved:["
								<< returned_double_data[n_component] << "]"
																		", expected:["
								<< uniform_value[n_component] << "]" << tcu::TestLog::EndMessage;

							result = false;
						}

						if (de::abs(returned_float_data[n_component] - uniform_value[n_component]) > epsilon)
						{
							m_testCtx.getLog()
								<< tcu::TestLog::Message
								<< "Invalid uniform value reported by glGetUniformfv() for uniform location ["
								<< uniform_location << "]"
													   " and component ["
								<< n_component << "]"
												  ": retrieved:["
								<< returned_float_data[n_component] << "]"
																	   ", expected:["
								<< uniform_value[n_component] << "]" << tcu::TestLog::EndMessage;

							result = false;
						}

						/* ints */
						int rounded_uniform_value_sint = (int)(deFloatRound((float)uniform_value[n_component]));
						unsigned int rounded_uniform_value_uint =
							(unsigned int)(uniform_value[n_component] > 0.0) ?
								((unsigned int)deFloatRound((float)uniform_value[n_component])) :
								0;

						if (returned_int_data[n_component] != rounded_uniform_value_sint)
						{
							m_testCtx.getLog()
								<< tcu::TestLog::Message
								<< "Invalid uniform value reported by glGetUniformiv() for uniform location ["
								<< uniform_location << "]"
													   " and component ["
								<< n_component << "]"
												  ": retrieved:["
								<< returned_int_data[n_component] << "]"
																	 ", expected:["
								<< rounded_uniform_value_sint << "]" << tcu::TestLog::EndMessage;

							result = false;
						}

						if (returned_uint_data[n_component] != rounded_uniform_value_uint)
						{
							m_testCtx.getLog()
								<< tcu::TestLog::Message
								<< "Invalid uniform value reported by glGetUniformuiv() for uniform location ["
								<< uniform_location << "]"
													   " and component ["
								<< n_component << "]"
												  ": retrieved:["
								<< returned_uint_data[n_component] << "]"
																	  ", expected:["
								<< rounded_uniform_value_uint << "]" << tcu::TestLog::EndMessage;

							result = false;
						}
					} /* for (all components) */
				}	 /* for (all uniform+value pairs) */
			}		  /* for (all 4 uniform types) */
		}			  /* for (all shader stages) */
	}				  /* for (both program objects) */

	/* All done! */
	return result;
}

/** Constructor
 *
 *  @param context Rendering context.
 */
GPUShaderFP64Test5::GPUShaderFP64Test5(deqp::Context& context)
	: TestCase(context, "conversions", "Verifies explicit and implicit casts involving double-precision"
									   " floating-point variables work correctly")
	, m_base_value_bo_data(DE_NULL)
	, m_base_value_bo_id(0)
	, m_has_test_passed(true)
	, m_po_base_value_attribute_location(-1)
	, m_po_id(0)
	, m_vao_id(0)
	, m_vs_id(0)
	, m_xfb_bo_id(0)
	, m_xfb_bo_size(0)
{
	/* Set up base value array (as per test spec) */
	m_base_values[0] = -25.12065f;
	m_base_values[1] = 0.0f;
	m_base_values[2] = 0.001f;
	m_base_values[3] = 1.0f;
	m_base_values[4] = 256.78901f;

	/* Set up swizzle matrix */
	m_swizzle_matrix[0][0] = SWIZZLE_TYPE_NONE;
	m_swizzle_matrix[0][1] = SWIZZLE_TYPE_Y;
	m_swizzle_matrix[0][2] = SWIZZLE_TYPE_Z;
	m_swizzle_matrix[0][3] = SWIZZLE_TYPE_W;
	m_swizzle_matrix[1][0] = SWIZZLE_TYPE_NONE;
	m_swizzle_matrix[1][1] = SWIZZLE_TYPE_YX;
	m_swizzle_matrix[1][2] = SWIZZLE_TYPE_ZY;
	m_swizzle_matrix[1][3] = SWIZZLE_TYPE_WX;
	m_swizzle_matrix[2][0] = SWIZZLE_TYPE_NONE;
	m_swizzle_matrix[2][1] = SWIZZLE_TYPE_YXX;
	m_swizzle_matrix[2][2] = SWIZZLE_TYPE_XZY;
	m_swizzle_matrix[2][3] = SWIZZLE_TYPE_XWZY;
	m_swizzle_matrix[3][0] = SWIZZLE_TYPE_NONE;
	m_swizzle_matrix[3][1] = SWIZZLE_TYPE_YXXY;
	m_swizzle_matrix[3][2] = SWIZZLE_TYPE_XZXY;
	m_swizzle_matrix[3][3] = SWIZZLE_TYPE_XZYW;
}

void GPUShaderFP64Test5::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_base_value_bo_data != DE_NULL)
	{
		delete[] m_base_value_bo_data;

		m_base_value_bo_data = DE_NULL;
	}

	if (m_base_value_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_base_value_bo_id);

		m_base_value_bo_id = 0;
	}

	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);

		m_vao_id = 0;
	}

	if (m_xfb_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_xfb_bo_id);

		m_xfb_bo_id = 0;
	}

	/* TCU_FAIL will skip the per sub test iteration de-initialization, we need to
	 * take care of it here
	 */
	deinitInteration();
}

/** Deinitializes all buffers and GL objects that may have been generated
 *  during test execution.
 **/
void GPUShaderFP64Test5::deinitInteration()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Executes a single test case iteration using user-provided test case descriptor.
 *
 *  This function may throw a TestError exception if GL implementation misbehaves.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return true if the values returned by GL implementation were found to be valid,
 *          false otherwise.
 **/
bool GPUShaderFP64Test5::executeIteration(const _test_case& test_case)
{
	bool result = true;

	/* Convert the base values array to the type of input attribute we'll be using
	 * for the iteration.
	 */
	Utils::_variable_type base_value_type = Utils::getBaseVariableType(test_case.src_type);

	if (base_value_type == Utils::VARIABLE_TYPE_BOOL)
	{
		/* bools are actually represented by ints, since bool varyings are not allowed */
		base_value_type = Utils::VARIABLE_TYPE_INT;
	}

	const unsigned int base_value_component_size = Utils::getBaseVariableTypeComponentSize(base_value_type);
	const unsigned int n_base_values			 = sizeof(m_base_values) / sizeof(m_base_values[0]);

	m_base_value_bo_data = new unsigned char[base_value_component_size * n_base_values];

	unsigned char* base_value_traveller_ptr = m_base_value_bo_data;

	for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value)
	{
		switch (base_value_type)
		{
		case Utils::VARIABLE_TYPE_DOUBLE:
			*((double*)base_value_traveller_ptr) = (double)m_base_values[n_base_value];
			break;
		case Utils::VARIABLE_TYPE_FLOAT:
			*((float*)base_value_traveller_ptr) = (float)m_base_values[n_base_value];
			break;
		case Utils::VARIABLE_TYPE_INT:
			*((int*)base_value_traveller_ptr) = (int)m_base_values[n_base_value];
			break;
		case Utils::VARIABLE_TYPE_UINT:
			*((unsigned int*)base_value_traveller_ptr) = (unsigned int)m_base_values[n_base_value];
			break;

		default:
		{
			TCU_FAIL("Unrecognized base value type");
		}
		}

		base_value_traveller_ptr += base_value_component_size;
	} /* for (all base values) */

	/* Update buffer object storage with the data we've just finished preparing. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bufferSubData(GL_ARRAY_BUFFER, 0 /* offset */, base_value_component_size * n_base_values, m_base_value_bo_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");

	/* Configure vertex attribute array corresponding to 'base_value' attribute, so that the
	 * new data is interpreted correctly.
	 */
	if (base_value_type == Utils::VARIABLE_TYPE_FLOAT)
	{
		gl.vertexAttribPointer(m_po_base_value_attribute_location, 1,							  /* size */
							   Utils::getGLDataTypeOfBaseVariableType(base_value_type), GL_FALSE, /* normalized */
							   0,																  /* stride */
							   DE_NULL);														  /* pointer */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");
	}
	else if (base_value_type == Utils::VARIABLE_TYPE_INT || base_value_type == Utils::VARIABLE_TYPE_UINT)
	{
		gl.vertexAttribIPointer(m_po_base_value_attribute_location, 1,						/* size */
								Utils::getGLDataTypeOfBaseVariableType(base_value_type), 0, /* stride */
								DE_NULL);													/* pointer */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer() call failed.");
	}
	else
	{
		DE_ASSERT(base_value_type == Utils::VARIABLE_TYPE_DOUBLE);

		gl.vertexAttribLPointer(m_po_base_value_attribute_location, 1, /* size */
								GL_DOUBLE, 0,						   /* stride */
								DE_NULL);							   /* pointer */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertxAttribLPointer() call failed.");
	}

	gl.enableVertexAttribArray(m_po_base_value_attribute_location);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed.");

	/* Execute the draw call */
	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	gl.beginTransformFeedback(GL_POINTS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
	{
		gl.drawArrays(GL_POINTS, 0 /* first */, n_base_values);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
	}
	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");

	/* Map the XFB buffer object into process space */
	void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
	DE_ASSERT(xfb_data_ptr != NULL);

	/* Verify the data */
	result &= verifyXFBData((const unsigned char*)xfb_data_ptr, test_case);

	/* Unmap the XFB BO */
	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");

	/** Good to release the data buffer at this point */
	if (m_base_value_bo_data != DE_NULL)
	{
		delete[] m_base_value_bo_data;

		m_base_value_bo_data = DE_NULL;
	}

	/* All done */
	return result;
}

/** Returns properties of a swizzle operator described by @param type swizzle type.
 *
 *  @param out_swizzle_string  Deref will be used to store a GLSL literal
 *                             corresponding to the specific swizzle operator.
 *                             Must not be NULL.
 *  @param out_n_components    Deref will be used to store the amount of components
 *                             used by the operator. Must not be NULL.
 *  @param out_component_order Deref will be used to store up to 4 integer values,
 *                             corresponding to component indices described by the
 *                             operator for a particular position.  Must not be NULL.
 **/
void GPUShaderFP64Test5::getSwizzleTypeProperties(_swizzle_type type, std::string* out_swizzle_string,
												  unsigned int* out_n_components, unsigned int* out_component_order)
{
	unsigned int result_component_order[4] = { 0 };
	unsigned int result_n_components	   = 0;
	std::string  result_swizzle_string;

	switch (type)
	{
	case SWIZZLE_TYPE_NONE:
	{
		result_swizzle_string = "";
		result_n_components   = 0;

		break;
	}

	case SWIZZLE_TYPE_XWZY:
	{
		result_swizzle_string	 = "xwzy";
		result_n_components		  = 4;
		result_component_order[0] = 0;
		result_component_order[1] = 3;
		result_component_order[2] = 2;
		result_component_order[3] = 1;

		break;
	}

	case SWIZZLE_TYPE_XZXY:
	{
		result_swizzle_string	 = "xzxy";
		result_n_components		  = 4;
		result_component_order[0] = 0;
		result_component_order[1] = 2;
		result_component_order[2] = 0;
		result_component_order[3] = 1;

		break;
	}

	case SWIZZLE_TYPE_XZY:
	{
		result_swizzle_string	 = "xzy";
		result_n_components		  = 3;
		result_component_order[0] = 0;
		result_component_order[1] = 2;
		result_component_order[2] = 1;

		break;
	}

	case SWIZZLE_TYPE_XZYW:
	{
		result_swizzle_string	 = "xzyw";
		result_n_components		  = 4;
		result_component_order[0] = 0;
		result_component_order[1] = 2;
		result_component_order[2] = 1;
		result_component_order[3] = 3;

		break;
	}

	case SWIZZLE_TYPE_Y:
	{
		result_swizzle_string	 = "y";
		result_n_components		  = 1;
		result_component_order[0] = 1;

		break;
	}

	case SWIZZLE_TYPE_YX:
	{
		result_swizzle_string	 = "yx";
		result_n_components		  = 2;
		result_component_order[0] = 1;
		result_component_order[1] = 0;

		break;
	}

	case SWIZZLE_TYPE_YXX:
	{
		result_swizzle_string	 = "yxx";
		result_n_components		  = 3;
		result_component_order[0] = 1;
		result_component_order[1] = 0;
		result_component_order[2] = 0;

		break;
	}

	case SWIZZLE_TYPE_YXXY:
	{
		result_swizzle_string	 = "yxxy";
		result_n_components		  = 4;
		result_component_order[0] = 1;
		result_component_order[1] = 0;
		result_component_order[2] = 0;
		result_component_order[3] = 1;

		break;
	}

	case SWIZZLE_TYPE_Z:
	{
		result_swizzle_string	 = "z";
		result_n_components		  = 1;
		result_component_order[0] = 2;

		break;
	}

	case SWIZZLE_TYPE_ZY:
	{
		result_swizzle_string	 = "zy";
		result_n_components		  = 2;
		result_component_order[0] = 2;
		result_component_order[1] = 1;

		break;
	}

	case SWIZZLE_TYPE_W:
	{
		result_swizzle_string	 = "w";
		result_n_components		  = 1;
		result_component_order[0] = 3;

		break;
	}

	case SWIZZLE_TYPE_WX:
	{
		result_swizzle_string	 = "wx";
		result_n_components		  = 2;
		result_component_order[0] = 3;
		result_component_order[1] = 0;

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized swizzle type");
	}
	} /* switch (type) */

	if (out_swizzle_string != DE_NULL)
	{
		*out_swizzle_string = result_swizzle_string;
	}

	if (out_n_components != DE_NULL)
	{
		*out_n_components = result_n_components;
	}

	if (out_component_order != DE_NULL)
	{
		memcpy(out_component_order, result_component_order, sizeof(unsigned int) * result_n_components);
	}
}

/** Returns body of a vertex shader that should be used for particular test case,
 *  given user-specified test case descriptor.
 *
 *  @param test_case Descriptor to use for the query.
 *
 *  @return Requested data.
 **/
std::string GPUShaderFP64Test5::getVertexShaderBody(const _test_case& test_case)
{
	std::stringstream  result;
	const std::string  base_type_string = Utils::getVariableTypeString(Utils::getBaseVariableType(test_case.src_type));
	const std::string  dst_type_string  = Utils::getVariableTypeString(test_case.dst_type);
	const unsigned int n_dst_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type);
	const unsigned int n_src_components = Utils::getNumberOfComponentsForVariableType(test_case.src_type);
	const std::string  src_type_string  = Utils::getVariableTypeString(test_case.src_type);

	/* Add version preamble */
	result << "#version 420\n"
			  "\n";

	/* Declare output variables. Note that boolean output variables are not supported, so we need
	 * to handle that special case correctly */
	if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL)
	{
		result << "out int result;\n";
	}
	else
	{
		result << "out " << dst_type_string << " result;\n";
	}

	/* Declare input variables. Handle the bool case exclusively. */
	if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL)
	{
		/* Use ints for bools. We will cast them to bool in the code later. */
		result << "in int base_value;\n";
	}
	else
	{
		result << "in " << base_type_string << " base_value;\n";
	}

	/* Declare main() and construct the value we will be casting from.
	 *
	 * Note: Addition operations on bool values cause an implicit conversion to int
	 *       which is not allowed. Hence, we skip these operations for this special
	 *       case.
	 */
	result << "void main()\n"
			  "{\n"
		   << src_type_string << " lside_value = ";

	if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL)
	{
		result << src_type_string << "(0 != ";
	}
	else
	{
		result << src_type_string << "(";
	}

	if (test_case.src_type != Utils::VARIABLE_TYPE_BOOL)
	{
		for (unsigned int n_component = 0; n_component < n_src_components; ++n_component)
		{
			result << "base_value + " << n_component;

			if (n_component != (n_src_components - 1))
			{
				result << ", ";
			}
		} /* for (all components) */
	}
	else
	{
		DE_ASSERT(n_src_components == 1);

		result << "base_value";
	}

	result << ");\n";

	/* Perform the casting operation. Add swizzle operator if possible. */
	if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL)
	{
		/* Handle the bool case exclusively */
		if (test_case.type == TEST_CASE_TYPE_EXPLICIT)
		{
			result << "result = (bool(lside_value) == false) ? 0 : 1";
		}
		else
		{
			result << "result = (lside_value == false) ? 0 : 1";
		}
	}
	else
	{
		if (test_case.type == TEST_CASE_TYPE_EXPLICIT)
		{
			result << "result = " << dst_type_string << "(lside_value)";
		}
		else
		{
			result << "result = lside_value";
		}
	}

	if (n_src_components > 1 && !Utils::isMatrixVariableType(test_case.src_type))
	{
		/* Add a swizzle operator  */
		DE_ASSERT(n_dst_components > 0 && n_dst_components <= 4);
		DE_ASSERT(n_src_components > 0 && n_src_components <= 4);

		unsigned int  swizzle_component_order[4] = { 0 };
		unsigned int  swizzle_n_components		 = 0;
		_swizzle_type swizzle_operator			 = m_swizzle_matrix[n_dst_components - 1][n_src_components - 1];
		std::string   swizzle_string;

		getSwizzleTypeProperties(swizzle_operator, &swizzle_string, &swizzle_n_components, swizzle_component_order);

		if (swizzle_n_components > 0)
		{
			result << "." << swizzle_string;
		}
	}

	/* Close the shader implementation. */
	result << ";\n"
			  "}\n";

	return result.str();
}

/** Initializes program & shader objects needed to run the iteration, given
 *  user-specified test case descriptor.
 *
 *  This function can throw a TestError exception if a GL error is detected
 *  during execution.
 *
 *  @param test_case Descriptor to use for the iteration.
 **/
void GPUShaderFP64Test5::initIteration(_test_case& test_case)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create program & shader objects */
	m_po_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");

	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");

	/* Configure shader body */
	std::string body		 = getVertexShaderBody(test_case);
	const char* body_raw_ptr = body.c_str();

	gl.shaderSource(m_vs_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	/* Store it in the test case descriptor for logging purposes */
	test_case.shader_body = body;

	/* Compile the shader */
	glw::GLint compile_status = GL_FALSE;

	gl.compileShader(m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

	if (compile_status != GL_TRUE)
	{
		TCU_FAIL("Shader compilation failed");
	}

	/* Attach the shader to the program obejct */
	gl.attachShader(m_po_id, m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");

	/* Configure XFB for the program object */
	const char* xfb_varying_name = "result";

	gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &xfb_varying_name, GL_INTERLEAVED_ATTRIBS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");

	/* Link the program object */
	glw::GLint link_status = GL_FALSE;

	gl.linkProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (link_status != GL_TRUE)
	{
		TCU_FAIL("Program linking failed");
	}

	/* Retrieve attribute locations */
	m_po_base_value_attribute_location = gl.getAttribLocation(m_po_id, "base_value");
	GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation() call failed.");

	if (m_po_base_value_attribute_location == -1)
	{
		TCU_FAIL("'base_value' is considered an inactive attribute which is invalid.");
	}
}

/** Initializes GL objects used by all test cases.
 *
 *  This function may throw a TestError exception if GL implementation reports
 *  an error at any point.
 **/
void GPUShaderFP64Test5::initTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Generate buffer object IDs */
	gl.genBuffers(1, &m_base_value_bo_id);
	gl.genBuffers(1, &m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");

	/* Allocate buffer object storage for 'base_value' input attribute data. All iterations
	 * will never eat up more than 1 double (as per test spec) and we will be drawing
	 * as many points in a single draw call as there are defined in m_base_values array.
	 */
	const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]);

	gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bufferData(GL_ARRAY_BUFFER, sizeof(double) * n_base_values, DE_NULL /* data */, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

	/* Allocate buffer object storage for XFB data. For each iteratiom we will be using
	 * five base values. Each XFBed value can take up to 16 components (eg. mat4) and be
	 * of double type (eg. dmat4), so make sure a sufficient amount of space is requested.
	 */
	const unsigned int xfb_bo_size = sizeof(double) * 16 /* components */ * n_base_values;

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");

	/* Allocate a client-side buffer to hold the data we will be mapping from XFB BO */
	m_xfb_bo_size = xfb_bo_size;

	/* Generate a vertex array object we will need to use for the draw calls */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");

	gl.bindVertexArray(m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test5::iterate()
{
	/* Do not execute the test if GL_ARB_texture_view is not supported */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
	}

	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit"))
	{
		throw tcu::NotSupportedError("GL_ARB_vertex_attrib_64bit is not supported.");
	}

	/* Initialize GL objects needed to run the tests */
	initTest();

	/* Build iteration array to run the tests in an automated manner */
	_test_case test_cases[] = {
		/* test case type */ /* source type */ /* destination type */
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, "" },
		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, "" },

		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_INT, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_UINT, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_FLOAT, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_BOOL, "" },
		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_BOOL, Utils::VARIABLE_TYPE_DOUBLE, "" }
	};
	const unsigned int n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);

	/* Execute all iterations */
	for (unsigned int n_test_case = 0; n_test_case < n_test_cases; ++n_test_case)
	{
		_test_case& test_case = test_cases[n_test_case];

		/* Initialize a program object we will use to perform the casting */
		initIteration(test_case);

		/* Use the program object to XFB the results */
		m_has_test_passed &= executeIteration(test_case);

		/* Release the GL Resource for this sub test */
		deinitInteration();

	} /* for (all test cases) */
	/* We're done */
	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Verifies if data XFBed out by the vertex shader are valid, given test case descriptor,
 *  for which the data have been generated.
 *
 *  @param data_ptr  Buffer holding the data XFBed out by the shader.
 *  @param test_case Descriptor of the test case, for which the vertex shader was
 *                   generated.
 *
 *  @return true if the data were found to be valid, false otherwise.
 **/
bool GPUShaderFP64Test5::verifyXFBData(const unsigned char* data_ptr, const _test_case& test_case)
{
	const Utils::_variable_type base_dst_type		= Utils::getBaseVariableType(test_case.dst_type);
	const Utils::_variable_type base_src_type		= Utils::getBaseVariableType(test_case.src_type);
	const float					epsilon				= 1e-5f;
	const unsigned int			n_base_values		= sizeof(m_base_values) / sizeof(m_base_values[0]);
	const unsigned int			n_result_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type);
	const unsigned int			n_src_components	= Utils::getNumberOfComponentsForVariableType(test_case.src_type);
	bool						result				= true;
	_swizzle_type				swizzle_operator	= SWIZZLE_TYPE_NONE;
	unsigned int				swizzle_order[4]	= { 0 };
	const unsigned char*		traveller_ptr		= data_ptr;

	if (!Utils::isMatrixVariableType(test_case.src_type))
	{
		DE_ASSERT(n_result_components >= 1 && n_result_components <= 4);
		DE_ASSERT(n_src_components >= 1 && n_src_components <= 4);

		swizzle_operator = m_swizzle_matrix[n_result_components - 1][n_src_components - 1];

		getSwizzleTypeProperties(swizzle_operator, DE_NULL, /* out_swizzle_string */
								 DE_NULL,					/* out_n_components */
								 swizzle_order);
	}

	for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value)
	{
		for (unsigned int n_result_component = 0; n_result_component < n_result_components; ++n_result_component)
		{
			unsigned int n_swizzled_component = n_result_component;

			if (swizzle_operator != SWIZZLE_TYPE_NONE)
			{
				n_swizzled_component =
					(n_result_component / n_result_components) * n_result_component + swizzle_order[n_result_component];
			}

			switch (base_dst_type)
			{
			case Utils::VARIABLE_TYPE_BOOL:
			case Utils::VARIABLE_TYPE_INT:
			{
				double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component);
				double expected_value	 = ref_expected_value;
				int	result_value		  = *((int*)traveller_ptr);

				if (base_dst_type == Utils::VARIABLE_TYPE_BOOL)
				{
					if (expected_value != 0.0)
					{
						expected_value = 1.0;
					}
				}

				if (result_value != (int)expected_value)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Invalid boolean/integer value obtained when doing an "
									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
									   << "]"
										  ", component index: ["
									   << n_swizzled_component << "]"
																  ", value: ["
									   << ref_expected_value << "]"
																" to GLSL type ["
									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
																							  ", retrieved value: ["
									   << result_value << "]"
														  ", expected value: ["
									   << (int)expected_value << "]"
																 ", shader used:\n"
									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;

					result = false;
				}

				traveller_ptr += sizeof(int);
				break;
			} /* VARIABLE_TYPE_BOOL or VARIABLE_TYPE_INT cases */

			case Utils::VARIABLE_TYPE_DOUBLE:
			{
				double ref_expected_value = m_base_values[n_base_value] + (double)n_swizzled_component;
				double expected_value	 = ref_expected_value;
				double result_value		  = *((double*)traveller_ptr);

				if (base_src_type == Utils::VARIABLE_TYPE_BOOL)
				{
					expected_value = ((int)expected_value != 0.0) ? 1.0 : 0.0;
				}
				else if (base_src_type == Utils::VARIABLE_TYPE_INT)
				{
					expected_value = (int)expected_value;
				}
				else if (base_src_type == Utils::VARIABLE_TYPE_UINT)
				{
					// Negative values in base values array when converted to unsigned int will be ZERO
					// Addition operations done inside the shader in such cases will operate on ZERO rather
					// than the negative value being passed.
					// Replicate the sequence of conversion and addition operations done on the
					// shader input, to calculate the expected values in XFB data in the
					// problematic cases.
					if (expected_value < 0)
					{
						expected_value = (unsigned int)m_base_values[n_base_value] + n_swizzled_component;
					}
					expected_value = (unsigned int)expected_value;
				}

				traveller_ptr += sizeof(double);
				if (de::abs(result_value - expected_value) > epsilon)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Invalid double-precision floating-point value obtained when doing an "
									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
									   << "]"
										  ", component index: ["
									   << n_swizzled_component << "]"
																  ", value: ["
									   << ref_expected_value << "]"
																" to GLSL type ["
									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
																							  ", retrieved value: ["
									   << std::setprecision(16) << result_value << "]"
																				   ", expected value: ["
									   << std::setprecision(16) << expected_value << "]"
																					 ", shader used:\n"
									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;

					result = false;
				}

				break;
			} /* VARIABLE_TYPE_DOUBLE case */

			case Utils::VARIABLE_TYPE_FLOAT:
			{
				float ref_expected_value = (float)m_base_values[n_base_value] + (float)n_swizzled_component;
				float expected_value	 = ref_expected_value;
				float result_value		 = *((float*)traveller_ptr);

				if (base_src_type == Utils::VARIABLE_TYPE_BOOL)
				{
					expected_value = (expected_value != 0.0f) ? 1.0f : 0.0f;
				}
				else if (base_src_type == Utils::VARIABLE_TYPE_INT)
				{
					expected_value = (float)((int)expected_value);
				}
				else if (base_src_type == Utils::VARIABLE_TYPE_UINT)
				{
					expected_value = (float)((unsigned int)expected_value);
				}

				traveller_ptr += sizeof(float);
				if (de::abs(result_value - expected_value) > epsilon)
				{
					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Invalid single-precision floating-point value obtained when doing an "
									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
									   << "]"
										  ", component index: ["
									   << n_swizzled_component << "]"
																  ", value: ["
									   << ref_expected_value << "]"
																" to GLSL type ["
									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
																							  ", retrieved value: ["
									   << std::setprecision(16) << result_value << "]"
																				   ", expected value: ["
									   << std::setprecision(16) << expected_value << "]"
																					 ", shader used:\n"
									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;

					result = false;
				}

				break;
			} /* VARIABLE_TYPE_FLOAT case */

			case Utils::VARIABLE_TYPE_UINT:
			{
				double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component);
				double expected_value	 = ref_expected_value;
				unsigned int result_value = *((unsigned int*)traveller_ptr);

				traveller_ptr += sizeof(unsigned int);
				if (result_value != (unsigned int)expected_value)
				{
					if (expected_value < 0.0)
					{
						// It is undefined to convert a negative floating-point value to an uint.
						break;
					}

					m_testCtx.getLog() << tcu::TestLog::Message
									   << "Invalid unsigned integer value obtained when doing an "
									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
									   << "]"
										  ", component index: ["
									   << n_swizzled_component << "]"
																  ", value: ["
									   << ref_expected_value << "]"
																" to GLSL type ["
									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
																							  ", retrieved value: ["
									   << result_value << "]"
														  ", expected value: ["
									   << (unsigned int)expected_value << "]"
																		  ", shader used:\n"
									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;

					result = false;
				}

				break;
			} /* VARIABLE_TYPE_UINT case */

			default:
			{
				TCU_FAIL("Unrecognized variable type");
			}
			} /* switch (test_case.dst_type) */
		}	 /* for (all result components) */
	}		  /* for (all base values) */

	return result;
}

/** Constructor
 *
 *  @param context Rendering context.
 */
GPUShaderFP64Test6::GPUShaderFP64Test6(deqp::Context& context)
	: TestCase(context, "illegal_conversions", "Verifies that invalid casts to double-precision variables are detected "
											   "during compilation time.")
	, m_cs_id(0)
	, m_fs_id(0)
	, m_gs_id(0)
	, m_tc_id(0)
	, m_te_id(0)
	, m_vs_id(0)
	, m_has_test_passed(true)
{
}

/** Deinitializes all buffers and GL objects that may have been generated
 *  during test execution.
 **/
void GPUShaderFP64Test6::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_cs_id != 0)
	{
		gl.deleteShader(m_cs_id);

		m_cs_id = 0;
	}

	if (m_fs_id != 0)
	{
		gl.deleteShader(m_fs_id);

		m_fs_id = 0;
	}

	if (m_gs_id != 0)
	{
		gl.deleteShader(m_gs_id);

		m_gs_id = 0;
	}

	if (m_tc_id != 0)
	{
		gl.deleteShader(m_tc_id);

		m_tc_id = 0;
	}

	if (m_te_id != 0)
	{
		gl.deleteShader(m_te_id);

		m_te_id = 0;
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Executes a single test case.
 *
 *  This function can throw TestError exceptions if GL implementation reports
 *  an error.
 *
 *  @param test_case Test case descriptor.
 *
 *  @return true if test case passed, false otherwise.
 **/
bool GPUShaderFP64Test6::executeIteration(const _test_case& test_case)
{
	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
	const glw::GLuint	 so_ids[]   = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
	const unsigned int	n_so_ids   = sizeof(so_ids) / sizeof(so_ids[0]);
	bool				  result	 = true;
	const char*			  stage_body = NULL;
	const char*			  stage_name = NULL;

	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
	{
		const glw::GLuint so_id = so_ids[n_so_id];

		/* Skip compute shader if it is not supported */
		if (0 == so_id)
		{
			continue;
		}

		/* Compile the shader */
		gl.compileShader(so_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

		/* Has the compilation failed as expected? */
		glw::GLint compile_status = GL_TRUE;

		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

		if (compile_status == GL_TRUE)
		{
			/* What is the current stage's name? */
			if (so_id == m_cs_id)
			{
				stage_body = test_case.cs_shader_body.c_str();
				stage_name = "Compute shader";
			}
			else if (so_id == m_fs_id)
			{
				stage_body = test_case.fs_shader_body.c_str();
				stage_name = "Fragment shader";
			}
			else if (so_id == m_gs_id)
			{
				stage_body = test_case.gs_shader_body.c_str();
				stage_name = "Geometry shader";
			}
			else if (so_id == m_tc_id)
			{
				stage_body = test_case.tc_shader_body.c_str();
				stage_name = "Tessellation control shader";
			}
			else if (so_id == m_te_id)
			{
				stage_body = test_case.te_shader_body.c_str();
				stage_name = "Tessellation evaluation shader";
			}
			else if (so_id == m_vs_id)
			{
				stage_body = test_case.vs_shader_body.c_str();
				stage_name = "Vertex shader";
			}
			else
			{
				/* Doesn't make much sense to throw exceptions here so.. */
				stage_body = "";
				stage_name = "[?]";
			}

			/* This shader should have never compiled successfully! */
			m_testCtx.getLog() << tcu::TestLog::Message << stage_name
							   << " has been compiled successfully, even though the shader was malformed."
								  " Following is shader body:\n"
							   << stage_body << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all shader objects) */

	return result;
}

/** Retrieves body of a compute shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test6::getComputeShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Add pre-amble */
	result_sstream << "#version 420\n"
					  "#extension GL_ARB_compute_shader          : require\n"
					  "\n"
					  "layout(local_size_x = 6) in;\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Add local variable declarations */
	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";

	if (test_case.src_array_size > 1)
	{
		result_sstream << "[" << test_case.src_array_size << "]";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "struct\n"
						  "{\n"
					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
	}
	else
	{
		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "\n} dst;\n";
	}

	/* Add actual body */
	result_sstream << "dst = src;\n"
					  "}\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a fragment shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test6::getFragmentShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Add pre-amble */
	result_sstream << "#version 420\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Add local variable declarations */
	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";

	if (test_case.src_array_size > 1)
	{
		result_sstream << "[" << test_case.src_array_size << "]";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "struct\n"
						  "{\n"
					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
	}
	else
	{
		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "\n} dst;\n";
	}

	/* Add actual body */
	result_sstream << "dst = src;\n"
					  "}\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a geometry shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test6::getGeometryShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Add preamble */
	result_sstream << "#version 420\n"
					  "\n"
					  "layout(points)                 in;\n"
					  "layout(max_vertices=1, points) out;\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Add local variable declarations */
	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";

	if (test_case.src_array_size > 1)
	{
		result_sstream << "[" << test_case.src_array_size << "]";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "struct\n"
						  "{\n"
					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
	}
	else
	{
		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
	}

	result_sstream << ";\n"
					  "\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "} dst;\n";
	}

	/* Add actual body */
	result_sstream << "dst = src;\n"
					  "}\n";

	/* We're done! */
	return result_sstream.str();
}

/** Retrieves body of a tesellation control shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test6::getTessellationControlShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Add preamble */
	result_sstream << "#version 420\n"
					  "\n"
					  "layout(vertices=4) out;\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Add local variable declarations. */
	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";

	if (test_case.src_array_size > 1)
	{
		result_sstream << "[" << test_case.src_array_size << "]";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "struct\n"
						  "{\n"
					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
	}
	else
	{
		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
	}

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << ";\n"
						  "} dst;\n";
	}
	else
	{
		result_sstream << ";\n";
	}

	/* Continue with the actual body. */
	result_sstream << "gl_TessLevelOuter[0] = 1.0;\n"
					  "gl_TessLevelOuter[1] = 1.0;\n"
					  "dst                  = src;\n"
					  "}\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a tessellation evaluation shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test6::getTessellationEvaluationShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Add preamble */
	result_sstream << "#version 420\n"
					  "\n"
					  "layout(isolines) in;\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Add local variable declarations */
	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";

	if (test_case.src_array_size > 1)
	{
		result_sstream << "[" << test_case.src_array_size << "]";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "struct\n"
						  "{\n"
					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
	}
	else
	{
		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
	}

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << ";\n"
						  "} dst;\n";
	}
	else
	{
		result_sstream << ";\n";
	}

	/* Continue with the actual body. */
	result_sstream << "dst = src;\n";

	/* Complete the body */
	result_sstream << "}\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a vertex shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test6::getVertexShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Add preamble */
	result_sstream << "#version 420\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Add local variables */
	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";

	if (test_case.src_array_size > 1)
	{
		result_sstream << "[" << test_case.src_array_size << "]";
	}

	result_sstream << ";\n";

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << "struct\n"
						  "{\n"
					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
	}
	else
	{
		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
	}

	if (test_case.wrap_dst_type_in_structure)
	{
		result_sstream << ";\n"
						  "} dst;\n";
	}
	else
	{
		result_sstream << ";\n";
	}

	/* Start actual body */
	result_sstream << "dst         = src;\n"
					  "gl_Position = vec4(1.0);\n"
					  "}";

	return result_sstream.str();
}

/** Initializes shader objects required to run the test. */
void GPUShaderFP64Test6::initTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Generate shader objects */

	/* Compute shader support and GL 4.2 required */
	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
	{
		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
	}

	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
	m_vs_id = gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
}

/** Assigns shader bodies to all shader objects that will be used for a single iteration.
 *
 *  @param test_case Test case descriptor to generate the shader bodies for.
 **/
void GPUShaderFP64Test6::initIteration(_test_case& test_case)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	test_case.cs_shader_body = getComputeShaderBody(test_case);
	test_case.fs_shader_body = getFragmentShaderBody(test_case);
	test_case.gs_shader_body = getGeometryShaderBody(test_case);
	test_case.tc_shader_body = getTessellationControlShaderBody(test_case);
	test_case.te_shader_body = getTessellationEvaluationShaderBody(test_case);
	test_case.vs_shader_body = getVertexShaderBody(test_case);

	/* Assign the bodies to relevant shaders */
	const char* cs_body_raw_ptr = test_case.cs_shader_body.c_str();
	const char* fs_body_raw_ptr = test_case.fs_shader_body.c_str();
	const char* gs_body_raw_ptr = test_case.gs_shader_body.c_str();
	const char* tc_body_raw_ptr = test_case.tc_shader_body.c_str();
	const char* te_body_raw_ptr = test_case.te_shader_body.c_str();
	const char* vs_body_raw_ptr = test_case.vs_shader_body.c_str();

	/* m_cs_id is initialized only if compute_shader is supported */
	if (0 != m_cs_id)
	{
		gl.shaderSource(m_cs_id, 1 /* count */, &cs_body_raw_ptr, DE_NULL /* length */);
	}

	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test6::iterate()
{
	/* Do not execute the test if GL_ARB_texture_view is not supported */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
	}

	/* Initialize GL objects needed to run the tests */
	initTest();

	/* Build iteration array to run the tests in an automated manner */
	_test_case test_cases[] = {
		/* Src array size */ /* Src type */ /* Dst type */ /* wrap_dst_type_in_structure */
		{ 2, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, true, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, false, "", "", "", "", "", "" },
		{ 2, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, true, "", "", "", "", "", "" }
	};
	const unsigned int n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);

	/* Execute all iterations */
	for (unsigned int n_test_case = 0; n_test_case < n_test_cases; ++n_test_case)
	{
		_test_case& test_case = test_cases[n_test_case];

		/* Initialize a program object we will use to perform the casting */
		initIteration(test_case);

		/* Use the program object to XFB the results */
		m_has_test_passed &= executeIteration(test_case);

	} /* for (all test cases) */

	/* We're done */
	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Constructor
 *
 *  @param context Rendering context.
 */
GPUShaderFP64Test7::GPUShaderFP64Test7(deqp::Context& context)
	: TestCase(context, "varyings", "Verifies double-precision floating-point varyings work correctly "
									"in all shader stages.")
	, m_are_double_inputs_supported(false)
	, m_fbo_id(0)
	, m_fs_id(0)
	, m_gs_id(0)
	, m_has_test_passed(true)
	, m_n_max_components_per_stage(0)
	, m_n_xfb_varyings(0)
	, m_po_id(0)
	, m_tc_id(0)
	, m_te_id(0)
	, m_to_id(0)
	, m_to_data(NULL)
	, m_to_height(4)
	, m_to_width(4)
	, m_xfb_bo_id(0)
	, m_xfb_varyings(NULL)
	, m_vao_id(0)
	, m_vs_id(0)
{
}

/** Compiles all shaders attached to test program object and links it.
 *
 *  @param variables
 *
 *  @return true if the process was executed successfully, false otherwise.
 */
bool GPUShaderFP64Test7::buildTestProgram(_variables& variables)
{
	std::string			  fs_body = getFragmentShaderBody(variables);
	const glw::Functions& gl	  = m_context.getRenderContext().getFunctions();
	std::string			  gs_body = getGeometryShaderBody(variables);
	std::string			  tc_body = getTessellationControlShaderBody(variables);
	std::string			  te_body = getTessellationEvaluationShaderBody(variables);
	std::string			  vs_body = getVertexShaderBody(variables);
	bool				  result  = false;

	/* Try to link the program object */
	glw::GLint link_status = GL_FALSE;

	/* Compile the shaders */
	if (!compileShader(m_fs_id, fs_body))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Fragment shader failed to compile." << tcu::TestLog::EndMessage;

		goto end;
	}

	if (!compileShader(m_gs_id, gs_body))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Geometry shader failed to compile." << tcu::TestLog::EndMessage;

		goto end;
	}

	if (!compileShader(m_tc_id, tc_body))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation control shader failed to compile."
						   << tcu::TestLog::EndMessage;

		goto end;
	}

	if (!compileShader(m_te_id, te_body))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation evaluation shader failed to compile."
						   << tcu::TestLog::EndMessage;

		goto end;
	}

	if (!compileShader(m_vs_id, vs_body))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Vertex shader failed to compile." << tcu::TestLog::EndMessage;

		goto end;
	}

	/* Configure XFB */
	releaseXFBVaryingNames();
	generateXFBVaryingNames(variables);

	gl.transformFeedbackVaryings(m_po_id, m_n_xfb_varyings, m_xfb_varyings, GL_INTERLEAVED_ATTRIBS);

	gl.linkProgram(m_po_id);

	/* Have we succeeded? */
	GLU_EXPECT_NO_ERROR(gl.getError(), "Either glTransformFeedbackVaryings() or glLinkProgram() call failed.");

	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (link_status != GL_TRUE)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "A valid program object failed to link."
						   << tcu::TestLog::EndMessage;

		goto end;
	}

	/* Retrieve attribute locations *if* GL_ARB_vertex_attrib_64bit is supported */
	if (m_are_double_inputs_supported)
	{
		const size_t n_variables = variables.size();

		for (size_t n_variable = 0; n_variable < n_variables; ++n_variable)
		{
			_variable&		  current_variable = variables[n_variable];
			std::stringstream attribute_name_sstream;

			attribute_name_sstream << "in_vs_variable" << n_variable;

			if (current_variable.array_size > 1)
			{
				attribute_name_sstream << "[0]";
			}

			current_variable.attribute_location = gl.getAttribLocation(m_po_id, attribute_name_sstream.str().c_str());

			if (current_variable.attribute_location == -1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Input double-precision attribute named ["
								   << attribute_name_sstream.str().c_str()
								   << "] is considered inactive which is invalid." << tcu::TestLog::EndMessage;

				m_has_test_passed = false;
				goto end;
			}
		} /* for (all test variables) */
	}	 /* if (m_are_double_inputs_supported) */

	m_current_fs_body = fs_body;
	m_current_gs_body = gs_body;
	m_current_tc_body = tc_body;
	m_current_te_body = te_body;
	m_current_vs_body = vs_body;

	result = true;

end:
	return result;
}

/** Updates shader object's body and then compiles the shader.
 *
 *  @param body Body to use for the shader.
 *
 *  @return true if the shader compiled successfully, false otherwise.
 **/
bool GPUShaderFP64Test7::compileShader(glw::GLint shader_id, const std::string& body)
{
	const char*			  body_raw_ptr   = body.c_str();
	glw::GLint			  compile_status = GL_FALSE;
	const glw::Functions& gl			 = m_context.getRenderContext().getFunctions();

	gl.shaderSource(shader_id, 1 /* count */, &body_raw_ptr, NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	gl.compileShader(shader_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &compile_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

	return (compile_status == GL_TRUE);
}

/** Configure storage of a buffer object used for capturing XFB data.
 *
 *  @param variables Holds descriptor for all variables used for the iteration the
 *                   BO is being configured for. Storage size will be directly related
 *                   to the number of the variables and their type.
 */
void GPUShaderFP64Test7::configureXFBBuffer(const _variables& variables)
{
	DE_ASSERT(m_n_xfb_varyings != 0);

	/* Geometry shaders outputs 4 vertices making up a triangle strip per draw call.
	 * The test only draws a single patch, and triangles are caught by transform feed-back.
	 * Let's initialize the storage, according to the list of variables that will be used
	 * for the test run.
	 */
	unsigned int bo_size = 0;

	for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
		 variables_iterator++)
	{
		const _variable& variable		= *variables_iterator;
		unsigned int	 n_bytes_needed = static_cast<unsigned int>(
			Utils::getNumberOfComponentsForVariableType(variable.type) * variable.array_size * sizeof(double));

		bo_size += n_bytes_needed;
	} /* for (all variables) */

	bo_size *= 3 /* vertices per triangle */ * 2; /* triangles emitted by geometry shader */

	/* Set up the BO storage */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
}

/** Deinitializes all buffers and GL objects that may have been generated
 *  during test execution.
 **/
void GPUShaderFP64Test7::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_fbo_id != 0)
	{
		gl.deleteFramebuffers(1, &m_fbo_id);

		m_fbo_id = 0;
	}

	if (m_fs_id != 0)
	{
		gl.deleteShader(m_fs_id);

		m_fs_id = 0;
	}

	if (m_gs_id != 0)
	{
		gl.deleteShader(m_gs_id);

		m_gs_id = 0;
	}

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}

	if (m_tc_id != 0)
	{
		gl.deleteShader(m_tc_id);

		m_tc_id = 0;
	}

	if (m_te_id != 0)
	{
		gl.deleteShader(m_te_id);

		m_te_id = 0;
	}

	if (m_to_data != NULL)
	{
		delete[] m_to_data;

		m_to_data = NULL;
	}

	if (m_to_id != 0)
	{
		gl.deleteTextures(1, &m_to_id);

		m_to_id = 0;
	}

	if (m_xfb_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_xfb_bo_id);

		m_xfb_bo_id = 0;
	}

	if (m_xfb_varyings != DE_NULL)
	{
		releaseXFBVaryingNames();
	}

	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);

		m_vao_id = 0;
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Executes the functional part of the test (case a) from the test spec)
 *
 *  @param variables Vector of variable descriptors defining properties of
 *                   variables that should be used for the iteration.
 *
 *  @return true if the test passed, false otherwise.
 **/
bool GPUShaderFP64Test7::executeFunctionalTest(_variables& variables)
{
	bool result = true;

	/* Build the test program */
	if (!buildTestProgram(variables))
	{
		return false;
	}

	/* Set up input attributes if GL_ARB_vertex_attrib_64bit extension is supported */
	if (m_are_double_inputs_supported)
	{
		setInputAttributeValues(variables);
	}

	/* Set up buffer object to hold XFB data. The data will be used for logging purposes
	 * only, if a data mismatch is detected.
	 */
	configureXFBBuffer(variables);

	/* Issue a draw call using the test program */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");

	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	gl.viewport(0, /* x */
				0, /* y */
				m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");

	gl.beginTransformFeedback(GL_TRIANGLES);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
	{
		gl.drawArrays(GL_PATCHES, 0 /* first */, 4 /* count */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
	}
	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");

	/* Verify color attachment contents */
	const float epsilon = 1.0f / 255.0f;

	gl.readPixels(0 /* x */, 0 /* y */, m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, m_to_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");

	for (unsigned int y = 0; y < m_to_height; ++y)
	{
		const unsigned char* row_ptr = m_to_data + 4 /* rgba */ * m_to_width * y;

		for (unsigned int x = 0; x < m_to_width; ++x)
		{
			const unsigned char* pixel_ptr = row_ptr + 4 /* rgba */ * x;

			if (de::abs(pixel_ptr[0]) > epsilon || de::abs(pixel_ptr[1] - 255) > epsilon ||
				de::abs(pixel_ptr[2]) > epsilon || de::abs(pixel_ptr[3]) > epsilon)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel found at (" << x << ", " << y
								   << ")"
									  "; expected:(0, 255, 0, 0), found: ("
								   << (int)pixel_ptr[0] << ", " << (int)pixel_ptr[1] << ", " << (int)pixel_ptr[2]
								   << ", " << (int)pixel_ptr[3]
								   << "), with the following variable types used as varyings:"
								   << tcu::TestLog::EndMessage;

				/* List the variable types that failed the test */
				const size_t n_variables = variables.size();

				for (size_t n_variable = 0; n_variable < n_variables; ++n_variable)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "gs_variable" << n_variable << ": "
									   << Utils::getVariableTypeString(variables[n_variable].type)
									   << " (array size:" << variables[n_variable].array_size << ")"
									   << tcu::TestLog::EndMessage;
				} /* for (all variable types) */

				/* Log the variable contents */
				logVariableContents(variables);

				/* Log shaders used for the iteration */
				m_testCtx.getLog() << tcu::TestLog::Message << "Shaders used:\n"
															   "\n"
															   "(VS):\n"
								   << m_current_vs_body.c_str() << "\n"
								   << "(TC):\n"
									  "\n"
								   << m_current_tc_body.c_str() << "\n"
																   "(TE):\n"
																   "\n"
								   << m_current_te_body.c_str() << "\n"
																   "(GS):\n"
								   << m_current_gs_body.c_str() << "\n"
																   "(FS):\n"
																   "\n"
								   << m_current_fs_body.c_str() << tcu::TestLog::EndMessage;

				result = false;

				goto end;
			}
		} /* for (all columns) */
	}	 /* for (all rows) */

/* All done! */
end:
	return result;
}

/** Takes user-input vector of test variables and allocates & fills an array of strings
 *  holding names of geometry shader stage varyings that should be captured during
 *  transform feedback operation. The array will be stored in m_xfb_varyings.
 *
 *  @param variables Holds all test variable descriptors to be used for the iteration.
 */
void GPUShaderFP64Test7::generateXFBVaryingNames(const _variables& variables)
{
	unsigned int n_variable = 0;
	unsigned int n_varying  = 0;
	unsigned int n_varyings = 0;

	if (m_xfb_varyings != NULL)
	{
		releaseXFBVaryingNames();
	}

	for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
		 ++variables_iterator)
	{
		const _variable& variable = *variables_iterator;

		n_varyings += variable.array_size;
	}

	m_xfb_varyings = new glw::GLchar*[n_varyings];

	for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
		 ++variables_iterator, ++n_variable)
	{
		const _variable& variable = *variables_iterator;

		for (unsigned int array_index = 0; array_index < variable.array_size; ++array_index, ++n_varying)
		{
			std::stringstream varying_sstream;
			size_t			  varying_length;

			varying_sstream << "gs_variable" << n_variable;

			if (variable.array_size > 1)
			{
				varying_sstream << "[" << array_index << "]";
			}

			/* Store the varying name */
			varying_length			  = varying_sstream.str().length();
			m_xfb_varyings[n_varying] = new glw::GLchar[varying_length + 1 /* terminator */];

			memcpy(m_xfb_varyings[n_varying], varying_sstream.str().c_str(), varying_length);
			m_xfb_varyings[n_varying][varying_length] = 0;
		} /* for (all array indices) */
	}	 /* for (all varyings) */

	m_n_xfb_varyings = n_varyings;
}

/** Retrieves body of a shader that defines input variable of user-specified type & array size
 *  without using the "flat" keyword. (case c) )
 *
 *  @param input_variable_type Variable type to use for input variable declaration.
 *  @param array_size          1 if the variable should not be arrayed; otherwise defines size
 *                             of the arrayed variable.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(
	Utils::_variable_type input_variable_type, unsigned int array_size)
{
	std::stringstream result_sstream;
	std::stringstream array_index_stringstream;
	std::stringstream array_size_stringstream;

	if (array_size > 1)
	{
		array_index_stringstream << "[0]";
		array_size_stringstream << "[" << array_size << "]";
	}

	if (Utils::isMatrixVariableType(input_variable_type))
	{
		array_index_stringstream << "[0].x";
	}
	else if (Utils::getNumberOfComponentsForVariableType(input_variable_type) > 1)
	{
		array_index_stringstream << "[0]";
	}

	result_sstream << "#version 400\n"
					  "\n"
					  "in "
				   << Utils::getVariableTypeString(input_variable_type) << " test_input"
				   << array_size_stringstream.str() << ";\n"
													   "\n"
													   "out float test_output;\n"
													   "\n"
													   "void main()\n"
													   "{\n"
													   "    if (test_input"
				   << array_index_stringstream.str() << " > 2.0)\n"
														"    {\n"
														"        test_output = 1.0;\n"
														"    }\n"
														"    else\n"
														"    {\n"
														"        test_output = 3.0;\n"
														"    }\n"
														"}\n";

	return result_sstream.str();
}

/** Retrieves body of a shader that defines double-precision floating-point output variable. (case b) ).
 *
 *  @param input_variable_type Variable type to use for input variable declaration.
 *  @param array_size          1 if the variable should not be arrayed; otherwise defines size
 *                             of the arrayed variable.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getCodeOfFragmentShaderWithDoublePrecisionOutput(
	Utils::_variable_type output_variable_type, unsigned int array_size)
{
	std::stringstream array_index_sstream;
	std::stringstream array_size_sstream;
	std::stringstream result_sstream;
	std::string		  output_variable_type_string = Utils::getVariableTypeString(output_variable_type);

	if (array_size > 1)
	{
		array_index_sstream << "[0]";
		array_size_sstream << "[" << array_size << "]";
	}

	result_sstream << "#version 400\n"
					  "\n"
					  "out "
				   << output_variable_type_string << " test_output" << array_size_sstream.str() << ";\n"
																								   "\n"
																								   "void main()\n"
																								   "{\n"
																								   "    test_output"
				   << array_index_sstream.str() << " = " << output_variable_type_string << "(2.0);\n"
																						   "}\n";

	return result_sstream.str();
}

/** Retrieves body of a fragment shader that uses user-specified set of variables
 *  to declare contents of input & output block.
 *
 *  @param variables As per description.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getFragmentShaderBody(const _variables& variables)
{
	std::stringstream result_sstream;

	/* Form the pre-amble */
	result_sstream << "#version 400\n"
					  "\n"

				   /* Add input block */
				   << "in GS_DATA\n"
					  "{\n"
				   << getVariableDeclarations("gs", variables, "flat") << "};\n"
																		  "\n"

				   /* Add output variable */
				   << "out vec4 result;\n"
					  "\n"

					  /* Add main() definition */
					  "void main()\n"
					  "{\n"
					  "const double epsilon = 1e-5;\n"
					  "\n"
					  "result = vec4(1, 0, 0, 0);\n"
					  "\n";

	/* Determine expected values first */
	unsigned int base_counter = 1;
	const size_t n_variables  = variables.size();

	for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
	{
		unsigned int		  variable_array_size		 = variables[n_variable].array_size;
		Utils::_variable_type variable_type				 = variables[n_variable].type;
		unsigned int		  n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
		std::string			  variable_type_string		 = Utils::getVariableTypeString(variable_type);

		std::stringstream array_size_sstream;

		if (variable_array_size > 1)
		{
			array_size_sstream << "[" << variable_array_size << "]";
		}

		/* Local variable declaration */
		result_sstream << variable_type_string << " expected_variable" << n_variable << array_size_sstream.str()
					   << ";\n"
						  "\n";

		/* Set expected values */
		for (unsigned int index = 0; index < variable_array_size; ++index)
		{
			std::stringstream array_index_sstream;

			if (variable_array_size > 1)
			{
				array_index_sstream << "[" << index << "]";
			}

			result_sstream << "expected_variable" << n_variable << array_index_sstream.str() << " = "
						   << variable_type_string << "(";

			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
			{
				unsigned int expected_value =
					(base_counter + 0) + (base_counter + 1) + (base_counter + 2) + (base_counter + 3);

				if (m_are_double_inputs_supported)
				{
					/* VS input attributes */
					//expected_value += (base_counter + 6);
					expected_value -= 1;
				}

				result_sstream << expected_value;

				if (n_component != (n_variable_type_components - 1))
				{
					result_sstream << ", ";
				}

				++base_counter;
			} /* for (all components) */

			result_sstream << ");\n";
		} /* for (all array indices) */

		result_sstream << "\n";
	} /* for (all variable types) */

	/* Now that we know the expected values, do a huge conditional check to verify if all
	 * input variables carry correct information.
	 */
	result_sstream << "if (";

	for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
	{
		unsigned int		  variable_array_size		 = variables[n_variable].array_size;
		Utils::_variable_type variable_type				 = variables[n_variable].type;
		bool				  is_variable_type_matrix	= Utils::isMatrixVariableType(variable_type);
		unsigned int		  n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
		std::string			  variable_type_string		 = Utils::getVariableTypeString(variable_type);

		for (unsigned int index = 0; index < variable_array_size; ++index)
		{
			std::stringstream array_index_sstream;

			if (variable_array_size > 1)
			{
				array_index_sstream << "[" << index << "]";
			}

			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
			{
				std::stringstream component_index_sstream;

				if (n_variable_type_components > 1)
				{
					component_index_sstream << "[" << n_component << "]";
				}

				result_sstream << "abs(expected_variable" << n_variable << array_index_sstream.str();

				if (is_variable_type_matrix)
				{
					const unsigned int n_columns = Utils::getNumberOfColumnsForVariableType(variable_type);
					const unsigned int column	= n_component % n_columns;
					const unsigned int row		 = n_component / n_columns;

					result_sstream << "[" << column << "]"
													   "."
								   << Utils::getComponentAtIndex(row);
				}
				else
				{
					result_sstream << component_index_sstream.str();
				}

				result_sstream << " - gs_variable" << n_variable << array_index_sstream.str();

				if (is_variable_type_matrix)
				{
					const unsigned int n_columns = Utils::getNumberOfColumnsForVariableType(variable_type);
					const unsigned int column	= n_component % n_columns;
					const unsigned int row		 = n_component / n_columns;

					result_sstream << "[" << column << "]"
													   "."
								   << Utils::getComponentAtIndex(row);
				}
				else
				{
					result_sstream << component_index_sstream.str();
				}

				result_sstream << ") <= epsilon &&";
			} /* for (all components) */
		}	 /* for (all array indices) */
	}		  /* for (all variable types) */

	result_sstream << "true)\n"
					  "{\n"
					  "    result = vec4(0, 1, 0, 0);\n"
					  "}\n"
					  "}\n";

	/* All done */
	return result_sstream.str();
}

/** Retrieves body of a geometry shader that uses user-specified set of variables
 *  to declare contents of input & output block.
 *
 *  @param variables As per description.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getGeometryShaderBody(const _variables& variables)
{
	std::stringstream result_sstream;

	/* Form the pre-amble */
	result_sstream << "#version 400\n"
					  "\n"
					  "layout(triangles)                      in;\n"
					  "layout(triangle_strip, max_vertices=4) out;\n"
					  "\n"

					  /* Add the input block */
					  "in TE_DATA\n"
					  "{\n"
				   << getVariableDeclarations("te", variables) << "} in_data[];\n"
																  "\n"

																  /* Add the output block */
																  "out GS_DATA\n"
																  "{\n"
				   << getVariableDeclarations("gs", variables, "flat") << "};\n"
																		  "\n"

																		  /* Declare main() function */
																		  "void main()\n"
																		  "{\n";

	/* Take input variables, add a predefined value and forward them to output variables */
	const float quad_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
									1.0f,  -1.0f, 0.0f, 1.0f, 1.0f,  1.0f, 0.0f, 1.0f };
	const unsigned int n_quad_vertices =
		sizeof(quad_vertices) / sizeof(quad_vertices[0]) / 4 /* components per vertex */;
	const size_t n_variables = variables.size();

	for (unsigned int n_quad_vertex = 0; n_quad_vertex < n_quad_vertices; ++n_quad_vertex)
	{
		unsigned int counter			 = 4;
		const float* current_quad_vertex = quad_vertices + n_quad_vertex * 4 /* components per vertex */;

		for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
		{
			unsigned int		  variable_array_size = variables[n_variable].array_size;
			Utils::_variable_type variable_type		  = variables[n_variable].type;
			unsigned int n_variable_type_components   = Utils::getNumberOfComponentsForVariableType(variable_type);
			std::string  variable_type_string		  = Utils::getVariableTypeString(variable_type);

			for (unsigned int index = 0; index < variable_array_size; ++index)
			{
				std::stringstream array_index_sstream;

				if (variable_array_size > 1)
				{
					array_index_sstream << "[" << index << "]";
				}

				result_sstream << "gs_variable" << n_variable << array_index_sstream.str()
							   << " = in_data[0].te_variable" << n_variable << array_index_sstream.str() << " + "
							   << variable_type_string << "(";

				for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
				{
					result_sstream << (counter++);

					if (n_component != (n_variable_type_components - 1))
					{
						result_sstream << ", ";
					}
				} /* for (all components) */

				result_sstream << ");\n";
			} /* for (all array indices) */
		}	 /* for (all variable types) */

		result_sstream << "gl_Position = vec4(" << current_quad_vertex[0] << ", " << current_quad_vertex[1] << ", "
					   << current_quad_vertex[2] << ", " << current_quad_vertex[3] << ");\n"
																					  "EmitVertex();\n";
	} /* for (all emitted quad vertices) */

	result_sstream << "EndPrimitive();\n"
					  "}\n";

	/* All done */
	return result_sstream.str();
}

/** Retrieves body of a tessellation control shader that uses user-specified set of variables
 *  to declare contents of input & output block.
 *
 *  @param variables As per description.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getTessellationControlShaderBody(const _variables& variables)
{
	std::stringstream result_sstream;

	/* Form the pre-amble */
	result_sstream << "#version 400\n"
					  "\n"
					  "layout (vertices=4) out;\n"

					  /* Declare input block */
					  "in VS_DATA\n"
					  "{\n"
				   << getVariableDeclarations("vs", variables) << "} in_data[];\n"

																  /* Declare output block */
																  "out TC_DATA\n"
																  "{\n"
				   << getVariableDeclarations("tc", variables) << "} out_data[];\n"
																  "\n"

																  /* Define main() */
																  "void main()\n"
																  "{\n"
																  "    gl_TessLevelInner[0] = 1;\n"
																  "    gl_TessLevelInner[1] = 1;\n"
																  "    gl_TessLevelOuter[0] = 1;\n"
																  "    gl_TessLevelOuter[1] = 1;\n"
																  "    gl_TessLevelOuter[2] = 1;\n"
																  "    gl_TessLevelOuter[3] = 1;\n"
																  "\n";

	/* Take input variables, add a predefined value and forward them to output variables */
	const size_t n_variables = variables.size();
	unsigned int counter	 = 2;

	for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
	{
		unsigned int		  variable_array_size		 = variables[n_variable].array_size;
		Utils::_variable_type variable_type				 = variables[n_variable].type;
		unsigned int		  n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
		std::string			  variable_type_string		 = Utils::getVariableTypeString(variable_type);

		for (unsigned int index = 0; index < variable_array_size; ++index)
		{
			std::stringstream array_index_sstream;

			if (variable_array_size > 1)
			{
				array_index_sstream << "[" << index << "]";
			}

			result_sstream << "out_data[gl_InvocationID].tc_variable" << n_variable << array_index_sstream.str()
						   << " = in_data[0].vs_variable" << n_variable << array_index_sstream.str() << " + "
						   << variable_type_string << "(";

			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
			{
				result_sstream << (counter++);

				if (n_component != (n_variable_type_components - 1))
				{
					result_sstream << ", ";
				}
			}

			result_sstream << ");\n";
		} /* for (all array indices) */
	}	 /* for (all variable types) */

	result_sstream << "}\n";

	/* We're done */
	return result_sstream.str();
}

/** Retrieves body of a tessellation evaluation shader that uses user-specified set of variables
 *  to declare contents of input & output block.
 *
 *  @param variables As per description.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getTessellationEvaluationShaderBody(const _variables& variables)
{
	std::stringstream result_sstream;

	/* Form the pre-amble */
	result_sstream << "#version 400\n"
					  "\n"
					  "layout(quads) in;\n"
					  "\n"

					  /* Define input block */
					  "in TC_DATA\n"
					  "{\n"
				   << getVariableDeclarations("tc", variables) << "} in_data[];\n"
																  "\n"

																  /* Define output block */
																  "out TE_DATA\n"
																  "{\n"
				   << getVariableDeclarations("te", variables) << "};\n"
																  "\n"

																  /* Define main() */
																  "void main()\n"
																  "{\n";

	/* Take input variables, add a predefined value and forward them to output variables */
	const size_t n_variables = variables.size();
	unsigned int counter	 = 3;

	for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
	{
		unsigned int		  variable_array_size		 = variables[n_variable].array_size;
		Utils::_variable_type variable_type				 = variables[n_variable].type;
		unsigned int		  n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
		std::string			  variable_type_string		 = Utils::getVariableTypeString(variable_type);

		for (unsigned int index = 0; index < variable_array_size; ++index)
		{
			std::stringstream array_index_sstream;

			if (variable_array_size > 1)
			{
				array_index_sstream << "[" << index << "]";
			}

			result_sstream << "te_variable" << n_variable << array_index_sstream.str() << " = in_data[0].tc_variable"
						   << n_variable << array_index_sstream.str() << " + " << variable_type_string << "(";

			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
			{
				result_sstream << (counter++);

				if (n_component != (n_variable_type_components - 1))
				{
					result_sstream << ", ";
				}
			} /* for (all components) */

			result_sstream << ");\n";
		} /* for (all array indices) */
	}	 /* for (all variable types) */

	result_sstream << "}\n";

	/* All done */
	return result_sstream.str();
}

/** Returns a string containing declarations of user-specified set of variables.
 *  Each declaration can optionally use a layot qualifier requested by the caller.
 *
 *  @param prefix             Prefix to use for variable names.
 *  @param variables          List of variables to declare in the result string.
 *  @param explicit_locations true if each declaration should explicitly define location
 *                            of the variable ( eg. (layout location=X) )
 *  @param layout_qualifier   Optional qualifier to use for the declaration. Must not
 *                            be NULL.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getVariableDeclarations(const char* prefix, const _variables& variables,
														const char* layout_qualifier)
{
	std::stringstream result_sstream;

	/* Define output variables */
	const size_t n_variables = variables.size();

	for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
	{
		unsigned int		  variable_array_size  = variables[n_variable].array_size;
		Utils::_variable_type variable_type		   = variables[n_variable].type;
		std::string			  variable_type_string = Utils::getVariableTypeString(variable_type);

		result_sstream << layout_qualifier << " " << variable_type_string << " " << prefix << "_variable" << n_variable;

		if (variable_array_size > 1)
		{
			result_sstream << "[" << variable_array_size << "]";
		}

		result_sstream << ";\n";
	} /* for (all user-specified variable types) */

	return result_sstream.str();
}

/** Retrieves body of a vertex shader that uses user-specified set of variables
 *  to declare contents of input & output block.
 *
 *  @param variables As per description.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test7::getVertexShaderBody(const _variables& variables)
{
	std::stringstream result_sstream;

	/* Form pre-amble */
	result_sstream << "#version 400\n"
					  "\n";

	/* Define input variables if GL_ARB_vertex_attrib_64bit is supported */
	if (m_are_double_inputs_supported)
	{
		result_sstream << "#extension GL_ARB_vertex_attrib_64bit : require\n"
					   << getVariableDeclarations("in_vs", variables, "in");
	}

	/* Define output variables */
	result_sstream << "out VS_DATA\n"
					  "{\n"
				   << getVariableDeclarations("vs", variables);

	/* Define main() */
	result_sstream << "};\n"
					  "\n"
					  "void main()\n"
					  "{\n";

	/* Set output variable values */
	unsigned int counter	 = 1;
	const size_t n_variables = variables.size();

	for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
	{
		unsigned int		  variable_array_size		 = variables[n_variable].array_size;
		Utils::_variable_type variable_type				 = variables[n_variable].type;
		const unsigned int	n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
		std::string			  variable_type_string		 = Utils::getVariableTypeString(variable_type);

		for (unsigned int index = 0; index < variable_array_size; ++index)
		{
			if (variable_array_size == 1)
			{
				result_sstream << "vs_variable" << n_variable << " = " << variable_type_string << "(";
			}
			else
			{
				result_sstream << "vs_variable" << n_variable << "[" << index << "]"
							   << " = " << variable_type_string << "(";
			}

			for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
			{
				result_sstream << (double)(counter++);

				/* Use input attributes, if available */
				if (m_are_double_inputs_supported)
				{
					result_sstream << " + in_vs_variable" << n_variable;

					if (variable_array_size > 1)
					{
						result_sstream << "[" << index << "]";
					}

					if (Utils::isMatrixVariableType(variables[n_variable].type))
					{
						const unsigned int n_columns = Utils::getNumberOfColumnsForVariableType(variable_type);
						const unsigned int column	= n_component % n_columns;
						const unsigned int row		 = n_component / n_columns;

						result_sstream << "[" << (column) << "]"
															 "."
									   << Utils::getComponentAtIndex(row);
					}
					else if (n_variable_type_components > 1)
					{
						result_sstream << "[" << n_component << "]";
					}
				}

				if (n_component != (n_variable_type_components - 1))
				{
					result_sstream << ", ";
				}
			} /* for (all components) */

			result_sstream << ");\n";
		}
	} /* for (all variable types) */

	/* We will be using geometry shader to lay out the actual vertices so
	 * the only thing we need to make sure is that the vertex never gets
	 * culled.
	 */
	result_sstream << "gl_Position = vec4(0, 0, 0, 1);\n"
					  "}\n";

	/* That's it */
	return result_sstream.str();
}

/** Initializes shader objects required to run the test. */
void GPUShaderFP64Test7::initTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Are double-precision input variables supported? */
	m_are_double_inputs_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit");

	/* Create a vertex array object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");

	gl.bindVertexArray(m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");

	/* Create a texture object we will use as FBO's color attachment */
	gl.genTextures(1, &m_to_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");

	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_to_width, m_to_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");

	/* Allocate temporary buffer to hold the texture data we will be reading
	 * from color attachment. */
	m_to_data = new unsigned char[m_to_width * m_to_height * 4 /* RGBA */];

	/* Create and set up a framebuffer object */
	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindframebuffer() call failed.");

	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");

	/* Create all shader objects */
	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");

	/* Create test program object */
	m_po_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");

	/* Attach the shaders to the program object */
	gl.attachShader(m_po_id, m_fs_id);
	gl.attachShader(m_po_id, m_gs_id);
	gl.attachShader(m_po_id, m_tc_id);
	gl.attachShader(m_po_id, m_te_id);
	gl.attachShader(m_po_id, m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");

	/* The test passes double-precision values through the whole rendering pipeline.
	 * This translates to a notable amount of components that we would need to transfer
	 * all values in one fell swoop. The number is large enough to exceed minimum
	 * capabilities as described for OpenGL 4.0 implementations.
	 * For that reason, the test executes in turns. Each turn is allocated as many
	 * double-precision scalar/matrix values as supported by the tested GL implementation.
	 */
	glw::GLint gl_max_fragment_input_components_value				  = 0;
	glw::GLint gl_max_geometry_input_components_value				  = 0;
	glw::GLint gl_max_geometry_output_components_value				  = 0;
	glw::GLint gl_max_tess_control_input_components_value			  = 0;
	glw::GLint gl_max_tess_control_output_components_value			  = 0;
	glw::GLint gl_max_tess_evaluation_input_components_value		  = 0;
	glw::GLint gl_max_tess_evaluation_output_components_value		  = 0;
	glw::GLint gl_max_transform_feedback_interleaved_components_value = 0;
	glw::GLint gl_max_vertex_output_components_value				  = 0;

	gl.getIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &gl_max_fragment_input_components_value);
	gl.getIntegerv(GL_MAX_GEOMETRY_INPUT_COMPONENTS, &gl_max_geometry_input_components_value);
	gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &gl_max_geometry_output_components_value);
	gl.getIntegerv(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, &gl_max_tess_control_input_components_value);
	gl.getIntegerv(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, &gl_max_tess_control_output_components_value);
	gl.getIntegerv(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, &gl_max_tess_evaluation_input_components_value);
	gl.getIntegerv(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, &gl_max_tess_evaluation_output_components_value);
	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
				   &gl_max_transform_feedback_interleaved_components_value);
	gl.getIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &gl_max_vertex_output_components_value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetintegerv() call(s) failed.");

	m_n_max_components_per_stage =
		de::min(gl_max_vertex_output_components_value, gl_max_tess_control_input_components_value);
	m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_fragment_input_components_value);
	m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_geometry_input_components_value);
	m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_geometry_output_components_value);
	m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_tess_control_output_components_value);
	m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_tess_evaluation_input_components_value);
	m_n_max_components_per_stage =
		de::min(m_n_max_components_per_stage, gl_max_tess_evaluation_output_components_value);
	m_n_max_components_per_stage =
		de::min(m_n_max_components_per_stage, gl_max_transform_feedback_interleaved_components_value);

	/* Update GL_PATCH_VERTICES setting so that we only use a single vertex to build
	 * the input patch */
	gl.patchParameteri(GL_PATCH_VERTICES, 1);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");

	/* Initialize a BO we will use to hold XFB data */
	gl.genBuffers(1, &m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test7::iterate()
{
	/* Do not execute the test if GL_ARB_texture_view is not supported */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
	}

	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit"))
	{
		throw tcu::NotSupportedError("GL_ARB_vertex_attrib_64bit is not supported.");
	}

	/* Initialize GL objects required to run the test */
	initTest();

	/* Check the negative cases first */
	const Utils::_variable_type double_variable_types[] = {
		Utils::VARIABLE_TYPE_DOUBLE,  Utils::VARIABLE_TYPE_DVEC2, Utils::VARIABLE_TYPE_DVEC3,
		Utils::VARIABLE_TYPE_DVEC4,   Utils::VARIABLE_TYPE_DMAT2, Utils::VARIABLE_TYPE_DMAT2X3,
		Utils::VARIABLE_TYPE_DMAT2X4, Utils::VARIABLE_TYPE_DMAT3, Utils::VARIABLE_TYPE_DMAT3X2,
		Utils::VARIABLE_TYPE_DMAT3X4, Utils::VARIABLE_TYPE_DMAT4, Utils::VARIABLE_TYPE_DMAT4X2,
		Utils::VARIABLE_TYPE_DMAT4X3,
	};
	const unsigned int n_double_variable_types = sizeof(double_variable_types) / sizeof(double_variable_types[0]);

	for (unsigned int n_double_variable_type = 0; n_double_variable_type < n_double_variable_types;
		 ++n_double_variable_type)
	{
		for (unsigned int array_size = 1; array_size < 3; ++array_size)
		{
			Utils::_variable_type variable_type = double_variable_types[n_double_variable_type];

			if (compileShader(m_fs_id, getCodeOfFragmentShaderWithDoublePrecisionOutput(variable_type, array_size)))
			{
				m_testCtx.getLog() << tcu::TestLog::Message
								   << "A fragment shader with double-precision output variable compiled successfully."
								   << tcu::TestLog::EndMessage;

				m_has_test_passed = false;
			}

			if (compileShader(m_fs_id,
							  getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(variable_type, array_size)))
			{
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "A fragment shader with double-precision input variables lacking flat layout qualifier"
					   " compiled successfully."
					<< tcu::TestLog::EndMessage;

				m_has_test_passed = false;
			}
		}
	} /* for (all variable types) */

	/* Execute functional test. Split the run into as many iterations as necessary
	 * so that we do not exceed GL implementation's capabilities. */
	unsigned int n_tested_variables = 0;
	_variables   variables_to_test;

	while (n_tested_variables != n_double_variable_types * 2 /* arrayed & non-arrayed */)
	{
		glw::GLint total_n_used_components = 0;

		/* Use as many variables as possible for the iterations. Do not exceed maximum amount
		 * of varying components that can be used for all shadr stages.
		 */
		while (total_n_used_components < m_n_max_components_per_stage &&
			   n_tested_variables != n_double_variable_types * 2 /* arrayed & non-arrayed */)
		{
			_variable	new_variable;
			unsigned int n_type_components = 0;
			glw::GLint   n_used_components = 0;

			new_variable.array_size =
				((n_tested_variables % 2) == 0) ? 1 /* non-arrayed variable */ : 2; /* arrayed variable */
			new_variable.type = double_variable_types[n_tested_variables / 2];

			/* Double-precision varyings can use twice as many components as single-precision FPs */
			n_type_components = 4 /* components per location */ *
								Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(new_variable.type);
			n_used_components = n_type_components * new_variable.array_size * 2;

			/* Do we have enough space? */
			if (total_n_used_components + n_used_components > m_n_max_components_per_stage)
			{
				if (n_used_components > m_n_max_components_per_stage)
				{ //if the number of components for this variable is larger than the max_components_per_stage, then skip it.
					n_tested_variables++;
				}
				break;
			}

			/* We can safely test the type in current iteration */
			total_n_used_components += n_used_components;
			n_tested_variables++;

			variables_to_test.push_back(new_variable);
		}

		if (variables_to_test.size() > 0)
		{
			m_has_test_passed &= executeFunctionalTest(variables_to_test);

			variables_to_test.clear();
		}
	}

	/* We're done */
	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Logs contents of test variables, as XFBed out by already executed test iteration. */
void GPUShaderFP64Test7::logVariableContents(const _variables& variables)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	std::stringstream	 log_sstream;

	log_sstream << "Test variable values as retrieved from geometry shader:\n";

	/* Map the XFB BO contents into process space */
	const void* xfb_bo_data = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");

	/* Read the variable contents. We only care about the set of varyings emitted
	 * for first vertex in the geometry shader */
	unsigned int		 n_varying	 = 0;
	const unsigned char* traveller_ptr = (const unsigned char*)xfb_bo_data;

	for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
		 ++variables_iterator, ++n_varying)
	{
		const _variable&			 variable			= *variables_iterator;
		const Utils::_variable_type& base_variable_type = Utils::getBaseVariableType(variable.type);
		const unsigned int			 n_components		= Utils::getNumberOfComponentsForVariableType(variable.type);

		for (unsigned int array_index = 0; array_index < variable.array_size; ++array_index)
		{
			log_sstream << "gs_variable" << n_varying;

			if (variable.array_size > 1)
			{
				log_sstream << "[" << array_index << "]";
			}

			log_sstream << ": (";

			for (unsigned int n_component = 0; n_component < n_components; ++n_component)
			{
				log_sstream << Utils::getStringForVariableTypeValue(base_variable_type, traveller_ptr);

				if (n_component != (n_components - 1))
				{
					log_sstream << ", ";
				}

				traveller_ptr += sizeof(double);
			}

			log_sstream << ")\n";
		} /* for (all array indices) */
	}	 /* for (all variables) */

	/* Unmap the BO */
	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");

	/* Pass the logged stream into the framework */
	m_testCtx.getLog() << tcu::TestLog::Message << log_sstream.str().c_str() << tcu::TestLog::EndMessage;
}

/** De-allocates an arary holding strings representing names of varyings that
 *  should be used for transform feed-back.
 **/
void GPUShaderFP64Test7::releaseXFBVaryingNames()
{
	for (unsigned int n_varying = 0; n_varying < m_n_xfb_varyings; ++n_varying)
	{
		delete[] m_xfb_varyings[n_varying];
	}

	delete[] m_xfb_varyings;
	m_xfb_varyings = DE_NULL;

	m_n_xfb_varyings = 0;
}

/** This function should only be called if GL_ARB_vertex_attrib_64bit extension is supported.
 *  Takes a list of test variables used for current iteration and assigns increasing values
 *  to subsequent input attributes of the test program.
 *
 *  @param variables Test variables of the current iteration.
 */
void GPUShaderFP64Test7::setInputAttributeValues(const _variables& variables)
{
	const glw::Functions& gl	  = m_context.getRenderContext().getFunctions();

	for (_variables_const_iterator variable_iterator = variables.begin(); variable_iterator != variables.end();
		 variable_iterator++)
	{
		const _variable&   variable			  = *variable_iterator;
		const bool		   is_matrix_type	 = Utils::isMatrixVariableType(variable.type);
		const unsigned int n_total_components = Utils::getNumberOfComponentsForVariableType(variable.type);
		unsigned int	   n_components		  = 0;
		unsigned int	   n_columns		  = 1;

		if (is_matrix_type)
		{
			n_columns	= Utils::getNumberOfColumnsForVariableType(variable.type);
			n_components = n_total_components / n_columns;

			DE_ASSERT(n_total_components % n_columns == 0);
		}
		else
		{
			n_components = n_total_components;
		}

		DE_ASSERT(n_components >= 1 && n_components <= 4);

		for (unsigned int index = 0; index < n_columns * variable.array_size; ++index)
		{
			const double data[] = { -1, -1, -1, -1 };

			switch (n_components)
			{
			case 1:
			{
				gl.vertexAttribL1dv(variable.attribute_location + index, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib1dv() call failed.");

				break;
			}

			case 2:
			{
				gl.vertexAttribL2dv(variable.attribute_location + index, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib2dv() call failed.");

				break;
			}

			case 3:
			{
				gl.vertexAttribL3dv(variable.attribute_location + index, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib3dv() call failed.");

				break;
			}

			case 4:
			{
				gl.vertexAttribL4dv(variable.attribute_location + index, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib4dv() call failed.");

				break;
			}

			default:
			{
				TCU_FAIL("Unrecognized number of components");
			}
			} /* switch (n_components) */

			/* Make sure VAAs are disabled */
			gl.disableVertexAttribArray(variable.attribute_location + index);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray() call failed.");
		} /* for (all array indices) */
	}	 /* for (all variables) */
}

/** Constructor
 *
 *  @param context Rendering context.
 */
GPUShaderFP64Test8::GPUShaderFP64Test8(deqp::Context& context)
	: TestCase(context, "valid_constructors", "Verifies that valid double-precision floating-point constructors "
											  "are accepted during compilation stage")
	, m_cs_id(0)
	, m_fs_id(0)
	, m_gs_id(0)
	, m_tc_id(0)
	, m_te_id(0)
	, m_vs_id(0)
	, m_has_test_passed(true)
{
}

/** Deinitializes all buffers and GL objects that may have been generated
 *  during test execution.
 **/
void GPUShaderFP64Test8::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_cs_id != 0)
	{
		gl.deleteShader(m_cs_id);

		m_cs_id = 0;
	}

	if (m_fs_id != 0)
	{
		gl.deleteShader(m_fs_id);

		m_fs_id = 0;
	}

	if (m_gs_id != 0)
	{
		gl.deleteShader(m_gs_id);

		m_gs_id = 0;
	}

	if (m_tc_id != 0)
	{
		gl.deleteShader(m_tc_id);

		m_tc_id = 0;
	}

	if (m_te_id != 0)
	{
		gl.deleteShader(m_te_id);

		m_te_id = 0;
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Executes a single test case.
 *
 *  This function can throw TestError exceptions if GL implementation reports
 *  an error.
 *
 *  @param test_case Test case descriptor.
 *
 *  @return true if test case passed, false otherwise.
 **/
bool GPUShaderFP64Test8::executeIteration(const _test_case& test_case)
{
	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
	const glw::GLuint	 so_ids[]   = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
	const unsigned int	n_so_ids   = sizeof(so_ids) / sizeof(so_ids[0]);
	bool				  result	 = true;
	const char*			  stage_body = NULL;
	const char*			  stage_name = NULL;

	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
	{
		const glw::GLuint so_id = so_ids[n_so_id];

		/* Skip compute shader if it is not supported */
		if (0 == so_id)
		{
			continue;
		}

		/* Compile the shader */
		gl.compileShader(so_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

		/* Has the compilation succeeded as expected? */
		glw::GLint compile_status = GL_FALSE;

		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

		if (compile_status == GL_FALSE)
		{
			/* What is the current stage's name? */
			if (so_id == m_cs_id)
			{
				stage_body = test_case.cs_shader_body.c_str();
				stage_name = "Compute shader";
			}
			else if (so_id == m_fs_id)
			{
				stage_body = test_case.fs_shader_body.c_str();
				stage_name = "Fragment shader";
			}
			else if (so_id == m_gs_id)
			{
				stage_body = test_case.gs_shader_body.c_str();
				stage_name = "Geometry shader";
			}
			else if (so_id == m_tc_id)
			{
				stage_body = test_case.tc_shader_body.c_str();
				stage_name = "Tessellation control shader";
			}
			else if (so_id == m_te_id)
			{
				stage_body = test_case.te_shader_body.c_str();
				stage_name = "Tessellation evaluation shader";
			}
			else if (so_id == m_vs_id)
			{
				stage_body = test_case.vs_shader_body.c_str();
				stage_name = "Vertex shader";
			}
			else
			{
				/* Doesn't make much sense to throw exceptions here so.. */
				stage_body = "";
				stage_name = "[?]";
			}

			/* This shader should have never failed to compile! */
			m_testCtx.getLog() << tcu::TestLog::Message << stage_name
							   << " has not compiled successfully, even though the shader is valid."
								  " Following is shader's body:\n"
							   << stage_body << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* for (all shader objects) */

	return result;
}

/** Retrieves all argument lists that can be used to initialize a variable of user-specified
 *  type.
 *
 *  @param variable_type Variable type to return valid argument lists for.
 **/
GPUShaderFP64Test8::_argument_lists GPUShaderFP64Test8::getArgumentListsForVariableType(
	const Utils::_variable_type& variable_type)
{
	const Utils::_variable_type matrix_types[] = {
		Utils::VARIABLE_TYPE_DMAT2, Utils::VARIABLE_TYPE_DMAT2X3, Utils::VARIABLE_TYPE_DMAT2X4,
		Utils::VARIABLE_TYPE_DMAT3, Utils::VARIABLE_TYPE_DMAT3X2, Utils::VARIABLE_TYPE_DMAT3X4,
		Utils::VARIABLE_TYPE_DMAT4, Utils::VARIABLE_TYPE_DMAT4X2, Utils::VARIABLE_TYPE_DMAT4X3,
	};
	const Utils::_variable_type scalar_types[] = { Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_DVEC2,
												   Utils::VARIABLE_TYPE_DVEC3, Utils::VARIABLE_TYPE_DVEC4 };
	const unsigned int n_matrix_types	 = sizeof(matrix_types) / sizeof(matrix_types[0]);
	const unsigned int n_scalar_types	 = sizeof(scalar_types) / sizeof(scalar_types[0]);
	const int		   n_total_components = (int)Utils::getNumberOfComponentsForVariableType(variable_type);

	/* Construct the argument list tree root. Each node carries a counter that tells how many components
	 * have already been assigned. Nodes that eat up all components are considered leaves and do not have
	 * any children. Otherwise, each node is assigned as many children, as there are types that could be
	 * used to define a subsequent argument, and its counter is increased by the amount of components
	 * described by the type.
	 */
	_argument_list_tree_node root;

	root.n_components_used = 0;
	root.parent			   = NULL;
	root.type			   = variable_type;

	/* Fill till all leaves use up all available components */
	_argument_list_tree_node_queue nodes_queue;

	nodes_queue.push(&root);

	do
	{
		/* Pop the first item in the queue */
		_argument_list_tree_node* current_node_ptr = nodes_queue.front();
		nodes_queue.pop();

		/* Matrix variable types can be defined by a combination of non-matrix variable types OR
		 * a single matrix variable type.
		 *
		 * Let's handle the latter case first.
		 */
		const int n_components_remaining = n_total_components - current_node_ptr->n_components_used;

		if (Utils::isMatrixVariableType(current_node_ptr->type))
		{
			/* Iterate through all known matrix types. All the types can be used
			 * as a constructor, assuming only one value is used to define new matrix's
			 * contents. */
			for (unsigned int n_matrix_type = 0; n_matrix_type < n_matrix_types; ++n_matrix_type)
			{
				Utils::_variable_type new_argument_type = matrix_types[n_matrix_type];

				/* Construct a new child node. Since GLSL spec clearly states we must not use more
				 * than one constructor argument if the only argument is a matrix type, mark the node
				 * as if it defined all available components.
				 */
				_argument_list_tree_node* new_subnode = new _argument_list_tree_node;

				new_subnode->n_components_used = n_total_components;
				new_subnode->parent			   = current_node_ptr;
				new_subnode->type			   = new_argument_type;

				/* Add the descriptor to node list but do not add it to the queue. This would be
				 * a redundant operation, since no new children nodes would have been assigned to
				 * this node anyway.
				 */
				current_node_ptr->children.push_back(new_subnode);
			} /* for (all matrix types) */
		}	 /* if (current node's type is a matrix) */

		/* Now for a combination of non-matrix variable types.. */
		if (!Utils::isMatrixVariableType(current_node_ptr->type))
		{
			/* Iterate through all known scalar types */
			for (unsigned int n_scalar_type = 0; n_scalar_type < n_scalar_types; ++n_scalar_type)
			{
				Utils::_variable_type new_argument_type = scalar_types[n_scalar_type];
				const int n_new_argument_components = Utils::getNumberOfComponentsForVariableType(new_argument_type);

				/* Only use the scalar type if we don't exceed the amount of components we can define
				 * for requested type.
				 */
				if (n_new_argument_components <= n_components_remaining)
				{
					/* Form new node descriptor */
					_argument_list_tree_node* new_subnode = new _argument_list_tree_node;

					new_subnode->n_components_used = n_new_argument_components + current_node_ptr->n_components_used;
					new_subnode->parent			   = current_node_ptr;
					new_subnode->type			   = new_argument_type;

					current_node_ptr->children.push_back(new_subnode);
					nodes_queue.push(new_subnode);
				}
			} /* for (all scalar types) */
		}	 /* if (!Utils::isMatrixVariableType(current_node_ptr->type) ) */
	} while (nodes_queue.size() > 0);

	/* To construct the argument lists, traverse the tree. Each path from root to child
	 * gives us a single argument list.
	 *
	 * First, identify leaf nodes.
	 */
	_argument_list_tree_nodes leaf_nodes;

	nodes_queue.push(&root);

	do
	{
		_argument_list_tree_node* current_node_ptr = nodes_queue.front();
		nodes_queue.pop();

		if (current_node_ptr->children.size() == 0)
		{
			/* This is a leaf node !*/
			leaf_nodes.push_back(current_node_ptr);
		}
		else
		{
			/* Throw all children nodes to the queue */
			const unsigned int n_children_nodes = (unsigned int)current_node_ptr->children.size();

			for (unsigned int n_children_node = 0; n_children_node < n_children_nodes; ++n_children_node)
			{
				nodes_queue.push(current_node_ptr->children[n_children_node]);
			} /* for (all children nodes) */
		}
	} while (nodes_queue.size() > 0);

	/* For all leaf nodes, move up the tree and construct the argument lists. */
	const unsigned int n_leaf_nodes = (unsigned int)leaf_nodes.size();
	_argument_lists	result;

	for (unsigned int n_leaf_node = 0; n_leaf_node < n_leaf_nodes; ++n_leaf_node)
	{
		_argument_list			  argument_list;
		_argument_list_tree_node* current_node_ptr = leaf_nodes[n_leaf_node];

		do
		{
			if (current_node_ptr != &root)
			{
				if (argument_list.size() == 0)
				{
					argument_list.push_back(current_node_ptr->type);
				}
				else
				{
					argument_list.insert(argument_list.begin(), current_node_ptr->type);
				}
			}

			current_node_ptr = current_node_ptr->parent;
		} while (current_node_ptr != NULL);

		result.push_back(argument_list);
	} /* for (all leaf nodes) */

	return result;
}

/** Retrieves body of a compute shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test8::getComputeShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	result_sstream << "#version 420\n"
					  "#extension GL_ARB_compute_shader          : require\n"
					  "\n"
					  "layout(local_size_x = 1) in;\n"
					  "\n"
					  "void main()\n"
					  "{\n"
				   << getGeneralBody(test_case) << "}\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a fragment shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test8::getFragmentShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	result_sstream << "#version 420\n"
					  "\n"
					  "void main()\n"
					  "{\n"
				   << getGeneralBody(test_case) << "}\n"
												   "\n";

	/* Return the body */
	return result_sstream.str();
}

/** Returns a GLSL line that defines and initializes a variable as described by
 *  user-specified test case descriptor.
 *
 *  @param test_case Test case descriptor to use for the query.
 *
 *  @return As per description
 **/
std::string GPUShaderFP64Test8::getGeneralBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	std::string variable_type_string = Utils::getVariableTypeString(test_case.type);

	result_sstream << variable_type_string << " src = " << variable_type_string << "(";

	for (_argument_list_const_iterator argument_list_iterator = test_case.argument_list.begin();
		 argument_list_iterator != test_case.argument_list.end(); argument_list_iterator++)
	{
		const Utils::_variable_type argument_variable_type = *argument_list_iterator;
		std::string		   argument_variable_type_string   = Utils::getVariableTypeString(argument_variable_type);
		const unsigned int argument_n_components = Utils::getNumberOfComponentsForVariableType(argument_variable_type);

		if (argument_list_iterator != test_case.argument_list.begin())
		{
			result_sstream << ", ";
		}

		result_sstream << argument_variable_type_string << "(";

		for (unsigned int n_component = 0; n_component < argument_n_components; ++n_component)
		{
			result_sstream << (double)(n_component + 1);

			if (n_component != (argument_n_components - 1))
			{
				result_sstream << ", ";
			}
		} /* for (all argument components) */

		result_sstream << ")";
	} /* for (all arguments) */

	result_sstream << ");\n";

	return result_sstream.str();
}

/** Retrieves body of a geometry shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test8::getGeometryShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	result_sstream << "#version 420\n"
					  "\n"
					  "layout(points)                 in;\n"
					  "layout(max_vertices=1, points) out;\n"
					  "\n"
					  "void main()\n"
					  "{\n"
				   << getGeneralBody(test_case) << "}\n"
												   "\n";

	/* We're done! */
	return result_sstream.str();
}

/** Retrieves body of a tesellation control shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test8::getTessellationControlShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	result_sstream << "#version 420\n"
					  "\n"
					  "layout(vertices=4) out;\n"
					  "\n"
					  "void main()\n"
					  "{\n"
				   << getGeneralBody(test_case) << "}\n"
												   "\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a tessellation evaluation shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test8::getTessellationEvaluationShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	result_sstream << "#version 420\n"
					  "\n"
					  "layout(isolines) in;\n"
					  "\n"
					  "void main()\n"
					  "{\n"
				   << getGeneralBody(test_case) << "}\n"
												   "\n";

	/* Return the body */
	return result_sstream.str();
}

/** Retrieves body of a vertex shader that should be used for the purpose of
 *  user-specified test case.
 *
 *  @param test_case Test case descriptor to use.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test8::getVertexShaderBody(const _test_case& test_case)
{
	std::stringstream result_sstream;

	/* Form the body */
	result_sstream << "#version 420\n"
					  "\n"
					  "void main()\n"
					  "{\n"
				   << getGeneralBody(test_case) << "}\n"
												   "\n";

	return result_sstream.str();
}

/** Initializes shader objects required to run the test. */
void GPUShaderFP64Test8::initTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Generate shader objects */

	/* Compute shader support and GL 4.2 required */
	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
	{
		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
	}

	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
	m_vs_id = gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
}

/** Assigns shader bodies to all shader objects that will be used for a single iteration.
 *
 *  @param test_case Test case descriptor to generate the shader bodies for.
 **/
void GPUShaderFP64Test8::initIteration(_test_case& test_case)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	test_case.cs_shader_body = getComputeShaderBody(test_case);
	test_case.fs_shader_body = getFragmentShaderBody(test_case);
	test_case.gs_shader_body = getGeometryShaderBody(test_case);
	test_case.tc_shader_body = getTessellationControlShaderBody(test_case);
	test_case.te_shader_body = getTessellationEvaluationShaderBody(test_case);
	test_case.vs_shader_body = getVertexShaderBody(test_case);

	/* Assign the bodies to relevant shaders */
	const char* cs_body_raw_ptr = test_case.cs_shader_body.c_str();
	const char* fs_body_raw_ptr = test_case.fs_shader_body.c_str();
	const char* gs_body_raw_ptr = test_case.gs_shader_body.c_str();
	const char* tc_body_raw_ptr = test_case.tc_shader_body.c_str();
	const char* te_body_raw_ptr = test_case.te_shader_body.c_str();
	const char* vs_body_raw_ptr = test_case.vs_shader_body.c_str();

	/* m_cs_id is initialized only if compute_shader is supported */
	if (0 != m_cs_id)
	{
		gl.shaderSource(m_cs_id, 1 /* count */, &cs_body_raw_ptr, DE_NULL /* length */);
	}

	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */);
	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test8::iterate()
{
	/* Do not execute the test if GL_ARB_texture_view is not supported */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
	}

	/* Initialize GL objects needed to run the tests */
	initTest();

	/* Build iteration array to run the tests in an automated manner */
	const Utils::_variable_type variable_types[] = { Utils::VARIABLE_TYPE_DMAT2,   Utils::VARIABLE_TYPE_DMAT2X3,
													 Utils::VARIABLE_TYPE_DMAT2X4, Utils::VARIABLE_TYPE_DMAT3,
													 Utils::VARIABLE_TYPE_DMAT3X2, Utils::VARIABLE_TYPE_DMAT3X4,
													 Utils::VARIABLE_TYPE_DMAT4,   Utils::VARIABLE_TYPE_DMAT4X2,
													 Utils::VARIABLE_TYPE_DMAT4X3, Utils::VARIABLE_TYPE_DOUBLE,
													 Utils::VARIABLE_TYPE_DVEC2,   Utils::VARIABLE_TYPE_DVEC3,
													 Utils::VARIABLE_TYPE_DVEC4 };
	const unsigned int n_variable_types = sizeof(variable_types) / sizeof(variable_types[0]);

	for (unsigned int n_variable_type = 0; n_variable_type < n_variable_types; ++n_variable_type)
	{
		const Utils::_variable_type variable_type = variable_types[n_variable_type];

		/* Construct a set of argument lists valid for the variable type considered */
		_argument_lists argument_lists = getArgumentListsForVariableType(variable_type);

		for (_argument_lists_const_iterator argument_list_iterator = argument_lists.begin();
			 argument_list_iterator != argument_lists.end(); argument_list_iterator++)
		{
			/* Constructor thwe test case descriptor */
			_test_case test_case;

			test_case.argument_list = *argument_list_iterator;
			test_case.type			= variable_type;

			/* Initialize a program object we will use to perform the casting */
			initIteration(test_case);

			/* See if the shader compiles. */
			m_has_test_passed &= executeIteration(test_case);
		} /* for (all argument lists) */
	}	 /* for (all variable types) */

	/* We're done */
	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Constructor.
 *
 *  @param context Rendering context.
 *
 **/
GPUShaderFP64Test9::GPUShaderFP64Test9(deqp::Context& context)
	: TestCase(context, "operators", "Verifies that general and relational operators work "
									 "correctly when used against double-precision floating-"
									 "point types.")
	, m_has_test_passed(true)
	, m_po_id(0)
	, m_xfb_bo_id(0)
	, m_vao_id(0)
	, m_vs_id(0)
{
	/* Left blank intentionally */
}

/** Deinitializes all ES objects that may have been created during
 *  test execution.
 **/
void GPUShaderFP64Test9::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);

		m_po_id = 0;
	}

	if (m_xfb_bo_id != 0)
	{
		gl.deleteBuffers(1, &m_xfb_bo_id);

		m_xfb_bo_id = 0;
	}

	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() call failed.");
	}

	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);

		m_vs_id = 0;
	}
}

/** Executes a single test iteration using user-specified test case properties.
 *
 *  @param test_case Test case descriptor.
 *
 *  @return true if the pass was successful, false if the test should fail.
 **/
bool GPUShaderFP64Test9::executeTestIteration(const _test_case& test_case)
{
	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
	bool				  result = true;

	/* Activate the test program object */
	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");

	/* Draw a single point with XFB enabled */
	gl.beginTransformFeedback(GL_POINTS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
	{
		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
	}
	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");

	/* Map the XFB BO into process space */
	const void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");

	result = verifyXFBData(test_case, (const unsigned char*)xfb_data_ptr);

	/* Unmap the BO */
	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");

	return result;
}

/** Performs a matrix multiplication, given types of l-side and r-side matrices and stores the result
 *  under user-specified location.
 *
 *  @param matrix_a_type  Type of the l-side matrix.
 *  @param matrix_a_data  Row-ordered data of l-side matrix.
 *  @param matrix_b_type  Type of the r-side matrix.
 *  @param matrix_b_data  Row-ordered data of r-side matrix.
 *  @param out_result_ptr Deref to be used to store the multiplication result.
 **/
void GPUShaderFP64Test9::getMatrixMultiplicationResult(const Utils::_variable_type& matrix_a_type,
													   const std::vector<double>&   matrix_a_data,
													   const Utils::_variable_type& matrix_b_type,
													   const std::vector<double>& matrix_b_data, double* out_result_ptr)
{
	(void)matrix_b_type;
	using namespace tcu;
	/* To keep the code maintainable, we only consider cases relevant for this test */
	switch (matrix_a_type)
	{
	case Utils::VARIABLE_TYPE_DMAT2:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT2);

		tcu::Matrix2d matrix_a(&matrix_a_data[0]);
		tcu::Matrix2d matrix_b(&matrix_b_data[0]);
		tcu::Matrix2d result;

		matrix_a = transpose(matrix_a);
		matrix_b = transpose(matrix_b);
		result   = matrix_a * matrix_b;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 2 * 2);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT2X3:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT3X2);

		tcu::Matrix<double, 2, 3> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 3, 2> matrix_a_transposed;
		tcu::Matrix<double, 3, 2> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 2, 3> matrix_b_transposed;
		tcu::Matrix<double, 3, 3> result;

		matrix_a_transposed = transpose(matrix_a);
		matrix_b_transposed = transpose(matrix_b);
		result				= matrix_a_transposed * matrix_b_transposed;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 3 * 3);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT2X4:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT4X2);

		tcu::Matrix<double, 2, 4> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 4, 2> matrix_a_transposed;
		tcu::Matrix<double, 4, 2> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 2, 4> matrix_b_transposed;
		tcu::Matrix<double, 4, 4> result;

		matrix_a_transposed = transpose(matrix_a);
		matrix_b_transposed = transpose(matrix_b);
		result				= matrix_a_transposed * matrix_b_transposed;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 4 * 4);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT3:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT3);

		tcu::Matrix<double, 3, 3> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 3, 3> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 3, 3> result;

		matrix_a = transpose(matrix_a);
		matrix_b = transpose(matrix_b);
		result   = matrix_a * matrix_b;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 3 * 3);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT3X2:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT2X3);

		tcu::Matrix<double, 3, 2> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 2, 3> matrix_a_transposed;
		tcu::Matrix<double, 2, 3> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 3, 2> matrix_b_transposed;
		tcu::Matrix<double, 2, 2> result;

		matrix_a_transposed = transpose(matrix_a);
		matrix_b_transposed = transpose(matrix_b);
		result				= matrix_a_transposed * matrix_b_transposed;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 2 * 2);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT3X4:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT4X3);

		tcu::Matrix<double, 3, 4> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 4, 3> matrix_a_transposed;
		tcu::Matrix<double, 4, 3> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 3, 4> matrix_b_transposed;
		tcu::Matrix<double, 4, 4> result;

		matrix_a_transposed = transpose(matrix_a);
		matrix_b_transposed = transpose(matrix_b);
		result				= matrix_a_transposed * matrix_b_transposed;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 4 * 4);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT4:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT4);

		tcu::Matrix<double, 4, 4> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 4, 4> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 4, 4> result;

		matrix_a = transpose(matrix_a);
		matrix_b = transpose(matrix_b);
		result   = matrix_a * matrix_b;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 4 * 4);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT4X2:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT2X4);

		tcu::Matrix<double, 4, 2> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 2, 4> matrix_a_transposed;
		tcu::Matrix<double, 2, 4> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 4, 2> matrix_b_transposed;
		tcu::Matrix<double, 2, 2> result;

		matrix_a_transposed = transpose(matrix_a);
		matrix_b_transposed = transpose(matrix_b);
		result				= matrix_a_transposed * matrix_b_transposed;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 2 * 2);
		break;
	}

	case Utils::VARIABLE_TYPE_DMAT4X3:
	{
		DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT3X4);

		tcu::Matrix<double, 4, 3> matrix_a(&matrix_a_data[0]);
		tcu::Matrix<double, 3, 4> matrix_a_transposed;
		tcu::Matrix<double, 3, 4> matrix_b(&matrix_b_data[0]);
		tcu::Matrix<double, 4, 3> matrix_b_transposed;
		tcu::Matrix<double, 3, 3> result;

		matrix_a_transposed = transpose(matrix_a);
		matrix_b_transposed = transpose(matrix_b);
		result				= matrix_a_transposed * matrix_b_transposed;

		memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 3 * 3);
		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized matrix A type");
	}
	} /* switch (matrix_a_type) */
}

/** Returns GLSL operator representation of the user-specified operation.
 *
 *  @param operation_type Internal operation type to retrieve the operator for.
 *
 *  @return As per description.
 **/
const char* GPUShaderFP64Test9::getOperatorForOperationType(const _operation_type& operation_type)
{
	const char* result = NULL;

	switch (operation_type)
	{
	case OPERATION_TYPE_ADDITION:
		result = "+";
		break;
	case OPERATION_TYPE_DIVISION:
		result = "/";
		break;
	case OPERATION_TYPE_MULTIPLICATION:
		result = "*";
		break;
	case OPERATION_TYPE_SUBTRACTION:
		result = "-";
		break;

	case OPERATION_TYPE_PRE_DECREMENTATION:
	case OPERATION_TYPE_POST_DECREMENTATION:
	{
		result = "--";

		break;
	}

	case OPERATION_TYPE_PRE_INCREMENTATION:
	case OPERATION_TYPE_POST_INCREMENTATION:
	{
		result = "++";

		break;
	}

	default:
	{
		TCU_FAIL("Unrecognized operation type");
	}
	} /* switch(operation_type) */

	return result;
}

/** Returns a string representing user-specified operation type.
 *
 *  @param operation_type Operation type to return the literal for.
 *
 *  @return Requested string.
 **/
std::string GPUShaderFP64Test9::getOperationTypeString(const _operation_type& operation_type)
{
	std::string result = "[?]";

	switch (operation_type)
	{
	case OPERATION_TYPE_ADDITION:
		result = "addition";
		break;
	case OPERATION_TYPE_DIVISION:
		result = "division";
		break;
	case OPERATION_TYPE_MULTIPLICATION:
		result = "multiplication";
		break;
	case OPERATION_TYPE_SUBTRACTION:
		result = "subtraction";
		break;
	case OPERATION_TYPE_PRE_DECREMENTATION:
		result = "pre-decrementation";
		break;
	case OPERATION_TYPE_PRE_INCREMENTATION:
		result = "pre-incrementation";
		break;
	case OPERATION_TYPE_POST_DECREMENTATION:
		result = "post-decrementation";
		break;
	case OPERATION_TYPE_POST_INCREMENTATION:
		result = "post-incrementation";
		break;

	default:
	{
		TCU_FAIL("Unrecognized operation type");
	}
	}

	return result;
}

/** Returns body of a vertex shader that should be used for user-specified test case
 *  descriptor.
 *
 *  @param test_case Test case descriptor.
 *
 *  @return Requested GLSL shader body.
 **/
std::string GPUShaderFP64Test9::getVertexShaderBody(_test_case& test_case)
{
	std::stringstream  result_sstream;
	std::string		   result_variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
	std::string		   variable_type_fp_string = Utils::getFPVariableTypeStringForVariableType(test_case.variable_type);
	std::string		   variable_type_string	= Utils::getVariableTypeString(test_case.variable_type);
	const unsigned int n_variable_components   = Utils::getNumberOfComponentsForVariableType(test_case.variable_type);

	/* If we are to multiply matrices, we will need to use a different type
	 * for the result variable if either of the matrices is not square.
	 */
	if (test_case.operation_type == OPERATION_TYPE_MULTIPLICATION &&
		Utils::isMatrixVariableType(test_case.variable_type))
	{
		Utils::_variable_type result_variable_type;
		Utils::_variable_type transposed_matrix_variable_type =
			Utils::getTransposedMatrixVariableType(test_case.variable_type);

		result_variable_type =
			Utils::getPostMatrixMultiplicationVariableType(test_case.variable_type, transposed_matrix_variable_type);
		result_variable_type_string = Utils::getVariableTypeString(result_variable_type);

		test_case.result_variable_type = result_variable_type;
	}

	/* Form the pre-amble */
	result_sstream << "#version 400\n"
					  "\n"

					  /* Add output variables */
					  "out "
				   << result_variable_type_string << " result;\n"
													 "out ivec2 result_lt;\n"
													 "out ivec2 result_lte;\n"
													 "out ivec2 result_gt;\n"
													 "out ivec2 result_gte;\n"
													 "void main()\n"
													 "{\n";

	/* Form reference values */
	result_sstream << variable_type_string << " reference1 = " << variable_type_string << "(";

	for (unsigned int n_variable_component = 0; n_variable_component < n_variable_components; ++n_variable_component)
	{
		result_sstream << (n_variable_component + 1);

		if (n_variable_component != (n_variable_components - 1))
		{
			result_sstream << ", ";
		}
	} /* for (all variable components) */

	result_sstream << ");\n";

	for (unsigned int n_ref2_case = 0; n_ref2_case < 2; /* single- and double-precision cases */
		 ++n_ref2_case)
	{
		Utils::_variable_type compatible_variable_type = test_case.variable_type;

		if (Utils::isMatrixVariableType(compatible_variable_type) &&
			test_case.operation_type == OPERATION_TYPE_MULTIPLICATION)
		{
			compatible_variable_type = Utils::getTransposedMatrixVariableType(compatible_variable_type);
		}

		std::string ref2_variable_type_fp_string =
			Utils::getFPVariableTypeStringForVariableType(compatible_variable_type);
		std::string ref2_variable_type_string = Utils::getVariableTypeString(compatible_variable_type);
		std::string ref2_variable_type = (n_ref2_case == 0) ? ref2_variable_type_fp_string : ref2_variable_type_string;
		std::string ref2_variable_name = (n_ref2_case == 0) ? "reference2f" : "reference2";

		result_sstream << ref2_variable_type << " " << ref2_variable_name << " = " << ref2_variable_type << "(";

		for (unsigned int n_variable_component = 0; n_variable_component < n_variable_components;
			 ++n_variable_component)
		{
			result_sstream << (n_variable_components - (n_variable_component + 1));

			if (n_variable_component != (n_variable_components - 1))
			{
				result_sstream << ", ";
			}
		} /* for (all variable components) */

		result_sstream << ");\n";
	} /* for (both reference2 declarations) */

	/* Add actual body */
	result_sstream << "\n"
					  "result = ";

	if (test_case.operation_type == OPERATION_TYPE_PRE_DECREMENTATION ||
		test_case.operation_type == OPERATION_TYPE_PRE_INCREMENTATION)
	{
		result_sstream << getOperatorForOperationType(test_case.operation_type);
	}

	result_sstream << "reference1 ";

	if (test_case.operation_type == OPERATION_TYPE_PRE_DECREMENTATION ||
		test_case.operation_type == OPERATION_TYPE_PRE_INCREMENTATION ||
		test_case.operation_type == OPERATION_TYPE_POST_DECREMENTATION ||
		test_case.operation_type == OPERATION_TYPE_POST_INCREMENTATION)
	{
		if (test_case.operation_type == OPERATION_TYPE_POST_DECREMENTATION ||
			test_case.operation_type == OPERATION_TYPE_POST_INCREMENTATION)
		{
			result_sstream << getOperatorForOperationType(test_case.operation_type);
		}
	}
	else
	{
		result_sstream << getOperatorForOperationType(test_case.operation_type) << " reference2";
	}

	result_sstream << ";\n";

	if (Utils::isScalarVariableType(test_case.variable_type))
	{
		result_sstream << "result_lt [0] = (reference1 <  reference2)  ? 1 : 0;\n"
						  "result_lt [1] = (reference1 <  reference2f) ? 1 : 0;\n"
						  "result_lte[0] = (reference1 <= reference2)  ? 1 : 0;\n"
						  "result_lte[1] = (reference1 <= reference2f) ? 1 : 0;\n"
						  "result_gt [0] = (reference1 >  reference2)  ? 1 : 0;\n"
						  "result_gt [1] = (reference1 >  reference2f) ? 1 : 0;\n"
						  "result_gte[0] = (reference1 >= reference2)  ? 1 : 0;\n"
						  "result_gte[1] = (reference1 >= reference2f) ? 1 : 0;\n";
	}
	else
	{
		result_sstream << "result_lt [0] = 1;\n"
						  "result_lt [1] = 1;\n"
						  "result_lte[0] = 1;\n"
						  "result_lte[1] = 1;\n"
						  "result_gt [0] = 1;\n"
						  "result_gt [1] = 1;\n"
						  "result_gte[0] = 1;\n"
						  "result_gte[1] = 1;\n";
	}

	result_sstream << "}\n";

	/* All done */
	return result_sstream.str();
}

/** Initializes all GL objects required to run the test.
 *
 *  This function can throw a TestError exception if the implementation misbehaves.
 */
void GPUShaderFP64Test9::initTest()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Create program & vertex shader objects */
	m_po_id = gl.createProgram();
	m_vs_id = gl.createShader(GL_VERTEX_SHADER);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() or glCreateShader() call failed.");

	/* Attach the shader to the program */
	gl.attachShader(m_po_id, m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");

	/* Set up a buffer object */
	gl.genBuffers(1, &m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");

	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");

	/* Set up a vertex array object */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");

	gl.bindVertexArray(m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
}

/** Initializes all GL objects required to run an iteration described by
 *  user-specified test case descriptor.
 *
 *  @param test_case Test case descriptor to use for the initialization.
 **/
void GPUShaderFP64Test9::initTestIteration(_test_case& test_case)
{
	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
	std::string			  vs_body		  = getVertexShaderBody(test_case);
	const char*			  vs_body_raw_ptr = vs_body.c_str();

	/* Store the shader's body */
	test_case.vs_body = vs_body;

	/* Try to compile the shader */
	glw::GLint compile_status = GL_FALSE;

	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");

	gl.compileShader(m_vs_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");

	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");

	if (compile_status != GL_TRUE)
	{
		TCU_FAIL("Test shader compilation failed.");
	}

	/* Configure XFB */
	const char*		   xfb_names[] = { "result", "result_lt", "result_lte", "result_gt", "result_gte" };
	const unsigned int n_xfb_names = sizeof(xfb_names) / sizeof(xfb_names[0]);

	gl.transformFeedbackVaryings(m_po_id, n_xfb_names, xfb_names, GL_INTERLEAVED_ATTRIBS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");

	/* Try to link the program */
	glw::GLint link_status = GL_FALSE;

	gl.linkProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");

	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");

	if (link_status != GL_TRUE)
	{
		TCU_FAIL("Test program linking failure");
	}

	/* Set up XFB BO data storage */
	const unsigned int result_variable_size = static_cast<unsigned int>(
		Utils::getNumberOfComponentsForVariableType(test_case.result_variable_type) * sizeof(double));
	const unsigned int xfb_bo_size = static_cast<unsigned int>(
		result_variable_size + sizeof(int) * 2 /* ivec2s */ * 4); /* result_ output variables */

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult GPUShaderFP64Test9::iterate()
{
	/* Do not execute the test if GL_ARB_texture_view is not supported */
	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
	}

	/* Initialize all ES objects required to run all the checks */
	initTest();

	/* Iterate through all variable types we want to test */
	const Utils::_variable_type variable_types[] = { Utils::VARIABLE_TYPE_DMAT2,   Utils::VARIABLE_TYPE_DMAT2X3,
													 Utils::VARIABLE_TYPE_DMAT2X4, Utils::VARIABLE_TYPE_DMAT3,
													 Utils::VARIABLE_TYPE_DMAT3X2, Utils::VARIABLE_TYPE_DMAT3X4,
													 Utils::VARIABLE_TYPE_DMAT4,   Utils::VARIABLE_TYPE_DMAT4X2,
													 Utils::VARIABLE_TYPE_DMAT4X3, Utils::VARIABLE_TYPE_DOUBLE,
													 Utils::VARIABLE_TYPE_DVEC2,   Utils::VARIABLE_TYPE_DVEC3,
													 Utils::VARIABLE_TYPE_DVEC4 };
	const unsigned int n_variable_types = sizeof(variable_types) / sizeof(variable_types[0]);

	for (unsigned int n_variable_type = 0; n_variable_type < n_variable_types; ++n_variable_type)
	{
		/* Iterate through all operation types we want to check */
		for (unsigned int n_operation_type = 0; n_operation_type < OPERATION_TYPE_COUNT; ++n_operation_type)
		{
			_operation_type				 operation_type = (_operation_type)n_operation_type;
			const Utils::_variable_type& variable_type  = variable_types[n_variable_type];

			/* Construct test case descriptor */
			_test_case test_case;

			test_case.operation_type	   = operation_type;
			test_case.result_variable_type = variable_type;
			test_case.variable_type		   = variable_type;

			/* Run the iteration */
			initTestIteration(test_case);

			m_has_test_passed &= executeTestIteration(test_case);
		} /* for (all operation types) */
	}	 /* for (all variable types) */

	/* All done. */
	if (m_has_test_passed)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return STOP;
}

/** Verifies data XFBed out by the draw call for user-specified test case
 *  descriptor.
 *
 *  @param test_case Test case descriptor
 *  @param xfb_data  Buffer holding the data XFBed out during the draw call.
 *                   Must not be NULL.
 *
 *  @return true if the data was found to be correct, false otherwise.
 **/
bool GPUShaderFP64Test9::verifyXFBData(const _test_case& test_case, const unsigned char* xfb_data)
{
	const double	   epsilon = 1e-5;
	const unsigned int n_result_components =
		Utils::getNumberOfComponentsForVariableType(test_case.result_variable_type);
	bool		  result			  = true;
	const double* xfb_data_result	 = (const double*)xfb_data;
	const int*	xfb_data_result_lt  = (const int*)(xfb_data_result + n_result_components);
	const int*	xfb_data_result_lte = (const int*)xfb_data_result_lt + 2;  /* cast/non-cast cases */
	const int*	xfb_data_result_gt  = (const int*)xfb_data_result_lte + 2; /* cast/non-cast cases */
	const int*	xfb_data_result_gte = (const int*)xfb_data_result_gt + 2;  /* cast/non-cast cases */

	/* Prepare reference values */
	int					modifier;
	std::vector<double> reference1;
	std::vector<double> reference2;

	if (test_case.operation_type == OPERATION_TYPE_PRE_INCREMENTATION ||
		test_case.operation_type == OPERATION_TYPE_POST_INCREMENTATION)
	{
		modifier = 1;
	}
	else if (test_case.operation_type == OPERATION_TYPE_PRE_DECREMENTATION ||
			 test_case.operation_type == OPERATION_TYPE_POST_DECREMENTATION)
	{
		modifier = -1;
	}
	else
	{
		modifier = 0;
	}

	if (Utils::isMatrixVariableType(test_case.variable_type))
	{
		/* Matrices may be of different sizes so we need to compute the
		 * reference values separately for each matrix
		 */
		const Utils::_variable_type matrix_a_type = test_case.variable_type;
		const Utils::_variable_type matrix_b_type = Utils::getTransposedMatrixVariableType(test_case.variable_type);
		const unsigned int			n_matrix_a_components = Utils::getNumberOfComponentsForVariableType(matrix_a_type);
		const unsigned int			n_matrix_b_components = Utils::getNumberOfComponentsForVariableType(matrix_b_type);

		for (unsigned int n_component = 0; n_component < n_matrix_a_components; ++n_component)
		{
			reference1.push_back(modifier + n_component + 1);
		}

		for (unsigned int n_component = 0; n_component < n_matrix_b_components; ++n_component)
		{
			reference2.push_back(n_matrix_b_components - (n_component + 1));
		}
	} /* if (Utils::isMatrixVariableType(test_case.variable_type) */
	else
	{
		/* Generate as many components as will be expected for the result variable */
		for (unsigned int n_result_component = 0; n_result_component < n_result_components; ++n_result_component)
		{
			reference1.push_back(modifier + n_result_component + 1);
			reference2.push_back(n_result_components - (n_result_component + 1));
		}
	}

	/* Verify the result value(s) */
	if (test_case.operation_type == OPERATION_TYPE_MULTIPLICATION &&
		Utils::isMatrixVariableType(test_case.variable_type))
	{
		/* Matrix multiplication */
		double				  expected_result_data[4 * 4];
		Utils::_variable_type matrix_a_type = test_case.variable_type;
		Utils::_variable_type matrix_b_type = Utils::getTransposedMatrixVariableType(test_case.variable_type);

		getMatrixMultiplicationResult(matrix_a_type, reference1, matrix_b_type, reference2, expected_result_data);

		for (unsigned int n_component = 0; n_component < n_result_components; ++n_component)
		{
			if (de::abs(xfb_data_result[n_component] - expected_result_data[n_component]) > epsilon)
			{
				std::stringstream log_sstream;

				log_sstream << "Data returned for " << Utils::getVariableTypeString(matrix_a_type) << " * "
							<< Utils::getVariableTypeString(matrix_b_type)
							<< " matrix multiplication was incorrect; expected:(";

				for (unsigned int n_logged_component = 0; n_logged_component < n_result_components;
					 ++n_logged_component)
				{
					log_sstream << expected_result_data[n_logged_component];

					if (n_logged_component != (n_result_components - 1))
					{
						log_sstream << ", ";
					}
				} /* for (all components to be logged) */

				log_sstream << "), retrieved:(";

				for (unsigned int n_logged_component = 0; n_logged_component < n_result_components;
					 ++n_logged_component)
				{
					log_sstream << xfb_data_result[n_logged_component];

					if (n_logged_component != (n_result_components - 1))
					{
						log_sstream << ", ";
					}
				} /* for (all components to be logged) */

				log_sstream << ")";

				m_testCtx.getLog() << tcu::TestLog::Message << log_sstream.str().c_str() << tcu::TestLog::EndMessage;

				result = false;
				break;
			}
		} /* for (all result components) */
	}	 /* if (dealing with matrix multiplication) */
	else
	{
		for (unsigned int n_component = 0; n_component < n_result_components; ++n_component)
		{
			double expected_value = reference1[n_component];

			switch (test_case.operation_type)
			{
			case OPERATION_TYPE_ADDITION:
				expected_value += reference2[n_component];
				break;
			case OPERATION_TYPE_DIVISION:
				expected_value /= reference2[n_component];
				break;
			case OPERATION_TYPE_MULTIPLICATION:
				expected_value *= reference2[n_component];
				break;
			case OPERATION_TYPE_SUBTRACTION:
				expected_value -= reference2[n_component];
				break;

			case OPERATION_TYPE_PRE_DECREMENTATION:
			case OPERATION_TYPE_PRE_INCREMENTATION:
			{
				/* Modifier already applied */
				break;
			}

			case OPERATION_TYPE_POST_DECREMENTATION:
			case OPERATION_TYPE_POST_INCREMENTATION:
			{
				/* Need to reverse the modification for the purpose of the following check */
				expected_value -= modifier;

				break;
			}

			default:
			{
				TCU_FAIL("Unrecognized operation type");
			}
			} /* switch (test_case.operation_type) */

			if (de::abs(xfb_data_result[n_component] - expected_value) > epsilon)
			{
				std::string operation_type_string = getOperationTypeString(test_case.operation_type);
				std::string variable_type_string  = Utils::getVariableTypeString(test_case.variable_type);

				m_testCtx.getLog() << tcu::TestLog::Message << "Value(s) generated for variable type ["
								   << variable_type_string << "]"
															  " and operation type ["
								   << operation_type_string << "]"
															   " were found invalid."
								   << tcu::TestLog::EndMessage;

				result = false;
				break;
			} /* if (test case failed) */
		}	 /* for (all components) */
	}

	/* Verify the comparison operation results */
	if (Utils::isScalarVariableType(test_case.variable_type))
	{
		DE_ASSERT(n_result_components == 1);

		const bool expected_result_lt[2]  = { reference1[0] < reference2[0], reference1[0] < (float)reference2[0] };
		const bool expected_result_lte[2] = { reference1[0] <= reference2[0], reference1[0] <= (float)reference2[0] };
		const bool expected_result_gt[2]  = { reference1[0] > reference2[0], reference1[0] > (float)reference2[0] };
		const bool expected_result_gte[2] = { reference1[0] >= reference2[0], reference1[0] >= (float)reference2[0] };

		if ((xfb_data_result_lt[0] ? 1 : 0) != expected_result_lt[0] ||
			(xfb_data_result_lt[1] ? 1 : 0) != expected_result_lt[1])
		{
			std::string operation_type_string = getOperationTypeString(test_case.operation_type);
			std::string variable_type_string  = Utils::getVariableTypeString(test_case.variable_type);

			m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for lower-than operator used for "
														   "variable type ["
							   << variable_type_string << "]"
														  "and operation type ["
							   << operation_type_string << "]"
														   "was found invalid; expected:("
							   << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
							   << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
							   << tcu::TestLog::EndMessage;

			result = false;
		}

		if ((xfb_data_result_lte[0] ? 1 : 0) != expected_result_lte[0] ||
			(xfb_data_result_lte[1] ? 1 : 0) != expected_result_lte[1])
		{
			std::string operation_type_string = getOperationTypeString(test_case.operation_type);
			std::string variable_type_string  = Utils::getVariableTypeString(test_case.variable_type);

			m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for lower-than-or-equal operator used for "
														   "variable type ["
							   << variable_type_string << "]"
														  "and operation type ["
							   << operation_type_string << "]"
														   "was found invalid; expected:("
							   << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
							   << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
							   << tcu::TestLog::EndMessage;

			result = false;
		}

		if ((xfb_data_result_gt[0] ? 1 : 0) != expected_result_gt[0] ||
			(xfb_data_result_gt[1] ? 1 : 0) != expected_result_gt[1])
		{
			std::string operation_type_string = getOperationTypeString(test_case.operation_type);
			std::string variable_type_string  = Utils::getVariableTypeString(test_case.variable_type);

			m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for greater-than operator used for "
														   "variable type ["
							   << variable_type_string << "]"
														  "and operation type ["
							   << operation_type_string << "]"
														   "was found invalid; expected:("
							   << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
							   << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
							   << tcu::TestLog::EndMessage;

			result = false;
		}

		if ((xfb_data_result_gte[0] ? 1 : 0) != expected_result_gte[0] ||
			(xfb_data_result_gte[1] ? 1 : 0) != expected_result_gte[1])
		{
			std::string operation_type_string = getOperationTypeString(test_case.operation_type);
			std::string variable_type_string  = Utils::getVariableTypeString(test_case.variable_type);

			m_testCtx.getLog() << tcu::TestLog::Message
							   << "Values reported for greater-than-or-equal operator used for "
								  "variable type ["
							   << variable_type_string << "]"
														  "and operation type ["
							   << operation_type_string << "]"
														   "was found invalid; expected:("
							   << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
							   << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
							   << tcu::TestLog::EndMessage;

			result = false;
		}
	} /* if (Utils::isScalarVariableType(test_case.variable_type) ) */
	else
	{
		if (xfb_data_result_lt[0] != 1 || xfb_data_result_lt[1] != 1 || xfb_data_result_lte[0] != 1 ||
			xfb_data_result_lte[1] != 1 || xfb_data_result_gt[0] != 1 || xfb_data_result_gt[1] != 1 ||
			xfb_data_result_gte[0] != 1 || xfb_data_result_gte[1] != 1)
		{
			std::string operation_type_string = getOperationTypeString(test_case.operation_type);
			std::string variable_type_string  = Utils::getVariableTypeString(test_case.variable_type);

			m_testCtx.getLog() << tcu::TestLog::Message
							   << "Invalid value was reported for matrix variable type, for which "
								  " operator checks are not executed; variable type ["
							   << variable_type_string << "]"
														  "and operation type ["
							   << operation_type_string << "]" << tcu::TestLog::EndMessage;

			result = false;
		}
	}

	return result;
}

namespace TypeHelpers
{
/** Get base type for reference types
 *
 * @tparam T type
 **/
template <typename T>
class referenceToType
{
public:
	typedef T result;
};

template <typename T>
class referenceToType<const T&>
{
public:
	typedef T result;
};

/** Maps variable type with enumeration Utils::_variable_type
 *
 * @tparam T type
 **/
template <typename T>
class typeInfo;

template <>
class typeInfo<glw::GLboolean>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_BOOL;
};

template <>
class typeInfo<glw::GLdouble>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DOUBLE;
};

template <>
class typeInfo<tcu::UVec2>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_UVEC2;
};

template <>
class typeInfo<tcu::UVec3>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_UVEC3;
};

template <>
class typeInfo<tcu::UVec4>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_UVEC4;
};

template <>
class typeInfo<tcu::DVec2>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DVEC2;
};

template <>
class typeInfo<tcu::DVec3>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DVEC3;
};

template <>
class typeInfo<tcu::DVec4>
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DVEC4;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 2, 2> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT2;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 3, 2> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT2X3;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 4, 2> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT2X4;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 3, 3> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT3;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 2, 3> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT3X2;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 4, 3> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT3X4;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 4, 4> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT4;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 2, 4> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT4X2;
};

template <>
class typeInfo<tcu::Matrix<glw::GLdouble, 3, 4> >
{
public:
	static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT4X3;
};
} /* TypeHelpers */

/** Implementations of "math" functions required by "GPUShaderFP64Test10"
 *
 **/
namespace Math
{
template <typename T>
static T clamp(T x, T minVal, T maxVal);

template <int Size>
static tcu::Matrix<glw::GLdouble, Size, Size> cofactors(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix);

template <int Size>
static tcu::Vector<glw::GLuint, Size> convertBvecToUvec(const tcu::Vector<bool, Size>& src);

template <typename T>
static T determinant(T val);

template <typename T>
static T determinant(const tcu::Matrix<T, 2, 2>& mat);

template <typename T>
static T determinant(const tcu::Matrix<T, 3, 3>& mat);

template <typename T>
static T determinant(const tcu::Matrix<T, 4, 4>& mat);

template <int Size>
static tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminate(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix,
																glw::GLuint column, glw::GLuint row);

template <int Size>
static tcu::Vector<glw::GLuint, Size> equal(const tcu::Vector<glw::GLdouble, Size>& left,
											const tcu::Vector<glw::GLdouble, Size>& right);

static glw::GLdouble fma(glw::GLdouble a, glw::GLdouble b, glw::GLdouble c);

static glw::GLdouble fract(glw::GLdouble val);

template <typename T>
static T frexp(T val, glw::GLint& exp);

template <int Size>
static tcu::Vector<glw::GLuint, Size> greaterThan(const tcu::Vector<glw::GLdouble, Size>& left,
												  const tcu::Vector<glw::GLdouble, Size>& right);

template <int Size>
static tcu::Vector<glw::GLuint, Size> greaterThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
													   const tcu::Vector<glw::GLdouble, Size>& right);

template <int Size>
static tcu::Matrix<glw::GLdouble, Size, Size> inverse(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix);

static glw::GLdouble inverseSqrt(glw::GLdouble val);

static glw::GLuint isinf_impl(glw::GLdouble val);

static glw::GLuint isnan_impl(glw::GLdouble val);

template <typename T>
static T ldexp(T val, glw::GLint exp);

template <int Size>
static tcu::Vector<glw::GLuint, Size> lessThan(const tcu::Vector<glw::GLdouble, Size>& left,
											   const tcu::Vector<glw::GLdouble, Size>& right);

template <int Size>
static tcu::Vector<glw::GLuint, Size> lessThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
													const tcu::Vector<glw::GLdouble, Size>& right);

template <typename T>
static T max(T left, T right);

template <typename T>
static T min(T left, T right);

template <int		 Size>
static glw::GLdouble minor_impl(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix, glw::GLuint column,
								glw::GLuint row);

template <typename T>
static T mix(T left, T right, T weight);

template <typename T>
static T mod(T left, T right);

template <typename T>
static T modf(T val, T& integer);

template <typename T>
static T multiply(T left, T right);

template <int Size>
static tcu::Vector<glw::GLuint, Size> notEqual(const tcu::Vector<glw::GLdouble, Size>& left,
											   const tcu::Vector<glw::GLdouble, Size>& right);

template <int Cols, int Rows>
static tcu::Matrix<glw::GLdouble, Rows, Cols> outerProduct(const tcu::Vector<glw::GLdouble, Rows>& left,
														   const tcu::Vector<glw::GLdouble, Cols>& right);

static glw::GLdouble packDouble2x32(const tcu::UVec2& in);

template <typename T>
static T round(T t);

template <typename T>
static T roundEven(T t);

template <typename T>
static T sign(T t);

template <typename T>
static T smoothStep(T e0, T e1, T val);

template <typename T>
static T step(T edge, T val);

template <typename T, int Rows, int Cols>
static tcu::Matrix<T, Cols, Rows> transpose(const tcu::Matrix<T, Rows, Cols>& matrix);

template <typename T>
static T trunc(T t);

static tcu::UVec2 unpackDouble2x32(const glw::GLdouble& val);

template <typename T>
static T clamp(T x, T minVal, T maxVal)
{
	return min(max(x, minVal), maxVal);
}

template <int Size>
static tcu::Matrix<glw::GLdouble, Size, Size> cofactors(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix)
{
	tcu::Matrix<glw::GLdouble, Size, Size> result;

	for (glw::GLuint c = 0; c < Size; ++c)
	{
		for (glw::GLuint r = 0; r < Size; ++r)
		{
			const glw::GLdouble minor_value = minor_impl(matrix, c, r);

			result(r, c) = (1 == (c + r) % 2) ? -minor_value : minor_value;
		}
	}

	return result;
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> convertBvecToUvec(const tcu::Vector<bool, Size>& src)
{
	tcu::Vector<glw::GLuint, Size> result;

	for (glw::GLint i = 0; i < Size; ++i)
	{
		if (GL_FALSE != src[i])
		{
			result[i] = 1;
		}
		else
		{
			result[i] = 0;
		}
	}

	return result;
}

template <typename T>
static T det2(T _00, T _10, T _01, T _11)
{
	return _00 * _11 - _01 * _10;
}

template <typename T>
static T det3(T _00, T _10, T _20, T _01, T _11, T _21, T _02, T _12, T _22)
{
	return _00 * det2(_11, _21, _12, _22) - _10 * det2(_01, _21, _02, _22) + _20 * det2(_01, _11, _02, _12);
}

template <typename T>
static T det4(T _00, T _10, T _20, T _30, T _01, T _11, T _21, T _31, T _02, T _12, T _22, T _32, T _03, T _13, T _23,
			  T _33)
{
	return _00 * det3(_11, _21, _31, _12, _22, _32, _13, _23, _33) -
		   _10 * det3(_01, _21, _31, _02, _22, _32, _03, _23, _33) +
		   _20 * det3(_01, _11, _31, _02, _12, _32, _03, _13, _33) -
		   _30 * det3(_01, _11, _21, _02, _12, _22, _03, _13, _23);
}

template <typename T>
static T determinant(T val)
{
	return val;
}

template <typename T>
static T determinant(const tcu::Matrix<T, 2, 2>& mat)
{
	return det2(mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1));
}

template <typename T>
static T determinant(const tcu::Matrix<T, 3, 3>& mat)
{
	return det3(mat(0, 0), mat(0, 1), mat(0, 2), mat(1, 0), mat(1, 1), mat(1, 2), mat(2, 0), mat(2, 1), mat(2, 2));
}

template <typename T>
static T determinant(const tcu::Matrix<T, 4, 4>& mat)
{
	return det4(mat(0, 0), mat(0, 1), mat(0, 2), mat(0, 3), mat(1, 0), mat(1, 1), mat(1, 2), mat(1, 3), mat(2, 0),
				mat(2, 1), mat(2, 2), mat(2, 3), mat(3, 0), mat(3, 1), mat(3, 2), mat(3, 3));
}

template <int Size>
static tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminate(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix,
																glw::GLuint column, glw::GLuint row)
{
	// GCC sometimes diagnoses an incorrect out of bounds write here. The code has been verified to be correct.
#if (DE_COMPILER == DE_COMPILER_GCC)
#	pragma GCC diagnostic push
#	pragma GCC diagnostic ignored "-Warray-bounds"
#endif

	const glw::GLint eCol = static_cast<glw::GLint>(column);
	const glw::GLint eRow = static_cast<glw::GLint>(row);

	tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> result;

	for (glw::GLint c = 0; c < Size; ++c)
	{
		/* Skip eliminated column */
		if (eCol == c)
		{
			continue;
		}

		for (glw::GLint r = 0; r < Size; ++r)
		{
			/* Skip eliminated row */
			if (eRow == r)
			{
				continue;
			}

			const glw::GLint r_offset = (r > eRow) ? -1 : 0;
			const glw::GLint c_offset = (c > eCol) ? -1 : 0;

			result(r + r_offset, c + c_offset) = matrix(r, c);
		}
	}

	return result;

#if (DE_COMPILER == DE_COMPILER_GCC)
#	pragma GCC diagnostic pop
#endif
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> equal(const tcu::Vector<glw::GLdouble, Size>& left,
											const tcu::Vector<glw::GLdouble, Size>& right)
{
	return convertBvecToUvec(tcu::equal(left, right));
}

static glw::GLdouble fma(glw::GLdouble a, glw::GLdouble b, glw::GLdouble c)
{
	return a * b + c;
}

static glw::GLdouble fract(glw::GLdouble val)
{
	return val - floor(val);
}

template <typename T>
static T frexp(T val, glw::GLint& exp)
{
	return ::frexp(val, &exp);
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> greaterThan(const tcu::Vector<glw::GLdouble, Size>& left,
												  const tcu::Vector<glw::GLdouble, Size>& right)
{
	return convertBvecToUvec(tcu::greaterThan(left, right));
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> greaterThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
													   const tcu::Vector<glw::GLdouble, Size>& right)
{
	return convertBvecToUvec(tcu::greaterThanEqual(left, right));
}

template <int Size>
static tcu::Matrix<glw::GLdouble, Size, Size> inverse(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix)
{
	const tcu::Matrix<glw::GLdouble, Size, Size> cof	  = cofactors(matrix);
	const tcu::Matrix<glw::GLdouble, Size, Size> adjugate = tcu::transpose(cof);
	const glw::GLdouble det		= determinant(matrix);
	const glw::GLdouble inv_det = 1.0 / det;

	tcu::Matrix<glw::GLdouble, Size, Size> result = adjugate * inv_det;

	return result;
}

static glw::GLdouble inverseSqrt(glw::GLdouble val)
{
	const glw::GLdouble root = sqrt(val);

	return (1.0 / root);
}

static glw::GLuint isinf_impl(glw::GLdouble val)
{
	const glw::GLdouble infinity = std::numeric_limits<glw::GLdouble>::infinity();

	return ((infinity == val) || (-infinity == val));
}

static glw::GLuint isnan_impl(glw::GLdouble val)
{
	return val != val;
}

template <typename T>
static T ldexp(T val, glw::GLint exp)
{
	return ::ldexp(val, exp);
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> lessThan(const tcu::Vector<glw::GLdouble, Size>& left,
											   const tcu::Vector<glw::GLdouble, Size>& right)
{
	return convertBvecToUvec(tcu::lessThan(left, right));
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> lessThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
													const tcu::Vector<glw::GLdouble, Size>& right)
{
	return convertBvecToUvec(tcu::lessThanEqual(left, right));
}

template <typename T>
static T max(T left, T right)
{
	return (left >= right) ? left : right;
}

template <typename T>
static T min(T left, T right)
{
	return (left <= right) ? left : right;
}

template <int		 Size>
static glw::GLdouble minor_impl(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix, glw::GLuint column,
								glw::GLuint row)
{
	tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminated = eliminate(matrix, column, row);

	return determinant(eliminated);
}

template <>
glw::GLdouble minor_impl<2>(const tcu::Matrix<glw::GLdouble, 2, 2>& matrix, glw::GLuint column, glw::GLuint row)
{
	const glw::GLuint r = (0 == row) ? 1 : 0;
	const glw::GLuint c = (0 == column) ? 1 : 0;

	return matrix(r, c);
}

template <typename T>
static T mix(T left, T right, T weight)
{
	return left * (1 - weight) + right * (weight);
}

template <typename T>
static T mod(T left, T right)
{
	const T div_res = left / right;
	const T floored = floor(div_res);

	return left - right * floored;
}

template <typename T>
static T modf(T val, T& integer)
{
	return ::modf(val, &integer);
}

template <typename T>
static T multiply(T left, T right)
{
	T result = left * right;

	return result;
}

template <int Size>
static tcu::Vector<glw::GLuint, Size> notEqual(const tcu::Vector<glw::GLdouble, Size>& left,
											   const tcu::Vector<glw::GLdouble, Size>& right)
{
	return convertBvecToUvec(tcu::notEqual(left, right));
}

template <int Cols, int Rows>
static tcu::Matrix<glw::GLdouble, Rows, Cols> outerProduct(const tcu::Vector<glw::GLdouble, Rows>& left,
														   const tcu::Vector<glw::GLdouble, Cols>& right)
{
	tcu::Matrix<glw::GLdouble, Rows, 1>	left_mat;
	tcu::Matrix<glw::GLdouble, 1, Cols>	right_mat;
	tcu::Matrix<glw::GLdouble, Rows, Cols> result;

	for (glw::GLuint i = 0; i < Rows; ++i)
	{
		left_mat(i, 0) = left[i];
	}

	for (glw::GLuint i = 0; i < Cols; ++i)
	{
		right_mat(0, i) = right[i];
	}

	result = left_mat * right_mat;

	return result;
}

static glw::GLdouble packDouble2x32(const tcu::UVec2& in)
{
	const glw::GLuint buffer[2] = { in[0], in[1] };
	glw::GLdouble	 result;
	memcpy(&result, buffer, sizeof(result));
	return result;
}

template <typename T>
static T round(T t)
{
	T frac = fract(t);
	T res  = t - frac;

	if (((T)0.5) < frac)
	{
		res += ((T)1.0);
	}

	return res;
}

template <typename T>
static T roundEven(T t)
{
	T frac = fract(t);
	T res  = t - frac;

	if (((T)0.5) < frac)
	{
		res += ((T)1.0);
	}
	else if ((((T)0.5) == frac) && (0 != ((int)res) % 2))
	{
		res += ((T)1.0);
	}

	return res;
}

template <typename T>
static T sign(T t)
{
	if (0 > t)
	{
		return -1;
	}
	else if (0 == t)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

template <typename T>
static T smoothStep(T e0, T e1, T val)
{
	if (e0 >= val)
	{
		return 0;
	}

	if (e1 <= val)
	{
		return 1;
	}

	T temp = (val - e0) / (e1 - e0);

	T result = temp * temp * (3 - 2 * temp);

	return result;
}

template <typename T>
static T step(T edge, T val)
{
	if (edge > val)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

template <typename T, int Rows, int Cols>
static tcu::Matrix<T, Cols, Rows> transpose(const tcu::Matrix<T, Rows, Cols>& matrix)
{
	tcu::Matrix<T, Cols, Rows> result = tcu::transpose(matrix);

	return result;
}

template <typename T>
static T trunc(T t)
{
	const T abs_value	= de::abs(t);
	const T result_value = floor(abs_value);

	const T result = sign(t) * result_value;

	return result;
}

static tcu::UVec2 unpackDouble2x32(const glw::GLdouble& val)
{
	glw::GLuint* ptr = (glw::GLuint*)&val;
	tcu::UVec2   result(ptr[0], ptr[1]);

	return result;
}
} /* Math */

/** Enumeration of tested functions
 * *_AGAINT_SCALAR enums are used to call glsl function with mixed scalar and genDType arguments.
 * For example "max" can be called for (dvec3, double).
 **/
enum FunctionEnum
{
	FUNCTION_ABS = 0,
	FUNCTION_CEIL,
	FUNCTION_CLAMP,
	FUNCTION_CLAMP_AGAINST_SCALAR,
	FUNCTION_CROSS,
	FUNCTION_DETERMINANT,
	FUNCTION_DISTANCE,
	FUNCTION_DOT,
	FUNCTION_EQUAL,
	FUNCTION_FACEFORWARD,
	FUNCTION_FLOOR,
	FUNCTION_FMA,
	FUNCTION_FRACT,
	FUNCTION_FREXP,
	FUNCTION_GREATERTHAN,
	FUNCTION_GREATERTHANEQUAL,
	FUNCTION_INVERSE,
	FUNCTION_INVERSESQRT,
	FUNCTION_LDEXP,
	FUNCTION_LESSTHAN,
	FUNCTION_LESSTHANEQUAL,
	FUNCTION_LENGTH,
	FUNCTION_MATRIXCOMPMULT,
	FUNCTION_MAX,
	FUNCTION_MAX_AGAINST_SCALAR,
	FUNCTION_MIN,
	FUNCTION_MIN_AGAINST_SCALAR,
	FUNCTION_MIX,
	FUNCTION_MOD,
	FUNCTION_MOD_AGAINST_SCALAR,
	FUNCTION_MODF,
	FUNCTION_NORMALIZE,
	FUNCTION_NOTEQUAL,
	FUNCTION_OUTERPRODUCT,
	FUNCTION_PACKDOUBLE2X32,
	FUNCTION_REFLECT,
	FUNCTION_REFRACT,
	FUNCTION_ROUND,
	FUNCTION_ROUNDEVEN,
	FUNCTION_SIGN,
	FUNCTION_SMOOTHSTEP,
	FUNCTION_SMOOTHSTEP_AGAINST_SCALAR,
	FUNCTION_SQRT,
	FUNCTION_STEP,
	FUNCTION_STEP_AGAINST_SCALAR,
	FUNCTION_TRANSPOSE,
	FUNCTION_TRUNC,
	FUNCTION_UNPACKDOUBLE2X32,
	FUNCTION_ISNAN,
	FUNCTION_ISINF,
};

struct TypeDefinition
{
	std::string name;
	glw::GLuint n_columns;
	glw::GLuint n_rows;
};

/** Implementation of BuiltinFunctionTest test, description follows:
 *
 *  Verify double-precision support in common functions works correctly.
 *  All double-precision types that apply for particular cases should
 *  be tested for the following functions:
 *
 *  - abs();
 *  - ceil();
 *  - clamp();
 *  - cross();
 *  - determinant();
 *  - distance();
 *  - dot();
 *  - equal();
 *  - faceforward();
 *  - floor();
 *  - fma();
 *  - fract();
 *  - frexp();
 *  - greaterThan();
 *  - greaterThanEqual();
 *  - inverse();
 *  - inversesqrt();
 *  - ldexp();
 *  - lessThan();
 *  - lessThanEqual();
 *  - length();
 *  - matrixCompMult();
 *  - max();
 *  - min();
 *  - mix();
 *  - mod();
 *  - modf();
 *  - normalize();
 *  - notEqual();
 *  - outerProduct();
 *  - packDouble2x32();
 *  - reflect();
 *  - refract();
 *  - round();
 *  - roundEven();
 *  - sign();
 *  - smoothstep();
 *  - sqrt();
 *  - step();
 *  - transpose();
 *  - trunc();
 *  - unpackDouble2x32();
 *  - isnan();
 *  - isinf();
 *
 *  The test should work by creating a program object (for each case
 *  considered), to which a vertex shader should be attached. The
 *  shader should define input variables that should be used as
 *  arguments for the function in question. The result of the
 *  operation should then be XFBed back to the test, where the
 *  value should be verified.
 *
 *  Reference function implementation from pre-DEQP CTS framework
 *  should be ported to C for verification purposes where available.
 *
 *  The test should use 1024 different scalar/vector/matrix argument
 *  combinations. It should pass if all functions are determined
 *  to work correctly for all argument combinations used.
 **/
class BuiltinFunctionTest : public deqp::TestCase
{
public:
	/* Public methods */
	BuiltinFunctionTest(deqp::Context& context, std::string caseName, FunctionEnum function,
						TypeDefinition typeDefinition);

	virtual void						 deinit();
	virtual tcu::TestNode::IterateResult iterate();

	/** Base class of functionObject. Main goal of it is to keep function details toghether and hide calling code.
	 *
	 **/
	class functionObject
	{
	public:
		functionObject(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
					   Utils::_variable_type result_type);

		virtual ~functionObject()
		{
		}

		virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const = 0;

		virtual glw::GLuint			  getArgumentCount() const					  = 0;
		virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const = 0;
		glw::GLuint getArgumentComponents(glw::GLuint argument) const;
		glw::GLuint getArgumentComponentSize(glw::GLuint argument) const;
		glw::GLuint getArgumentOffset(glw::GLuint argument) const;
		glw::GLuint getArgumentStride() const;
		glw::GLuint getArgumentStride(glw::GLuint argument) const;
		FunctionEnum	   getFunctionEnum() const;
		const glw::GLchar* getName() const;
		glw::GLuint getResultComponents(glw::GLuint result) const;
		virtual glw::GLuint getResultCount() const;
		glw::GLuint getResultOffset(glw::GLuint result) const;
		virtual Utils::_variable_type getResultType(glw::GLuint result) const;
		glw::GLuint getResultStride(glw::GLuint result) const;
		glw::GLuint getBaseTypeSize(glw::GLuint result) const;
		glw::GLuint getResultStride() const;

	protected:
		const FunctionEnum			m_function_enum;
		const glw::GLchar*			m_function_name;
		const glw::GLvoid*			m_p_function;
		const Utils::_variable_type m_res_type;
	};

private:
	/* Private types */
	/** General type enumeration
	 *
	 **/
	enum generalType
	{
		SCALAR = 0,
		VECTOR,
		MATRIX,
	};

	/** Details of variable type
	 *
	 **/
	struct typeDetails
	{
		typeDetails(glw::GLuint n_columns, glw::GLuint n_rows);

		generalType m_general_type;
		glw::GLuint m_n_columns;
		glw::GLuint m_n_rows;
		glw::GLenum m_type;
		std::string m_type_name;
	};

	/* Typedefs for gl.uniform* function pointers */
	typedef GLW_APICALL void(GLW_APIENTRY* uniformDMatFunctionPointer)(glw::GLint, glw::GLsizei, glw::GLboolean,
																	   const glw::GLdouble*);
	typedef GLW_APICALL void(GLW_APIENTRY* uniformDVecFunctionPointer)(glw::GLint, glw::GLsizei, const glw::GLdouble*);
	typedef GLW_APICALL void(GLW_APIENTRY* uniformIVecFunctionPointer)(glw::GLint, glw::GLsizei, const glw::GLint*);
	typedef GLW_APICALL void(GLW_APIENTRY* uniformUVecFunctionPointer)(glw::GLint, glw::GLsizei, const glw::GLuint*);

	/* Private methods */
	bool compare(Utils::_variable_type type, const glw::GLvoid* left, const glw::GLvoid* right);

	functionObject* getFunctionObject(FunctionEnum function, const typeDetails& type);

	uniformDMatFunctionPointer getUniformFunctionForDMat(glw::GLuint		   argument,
														 const functionObject& function_object) const;

	uniformDVecFunctionPointer getUniformFunctionForDVec(glw::GLuint		   argument,
														 const functionObject& function_object) const;

	uniformIVecFunctionPointer getUniformFunctionForIVec(glw::GLuint		   argument,
														 const functionObject& function_object) const;

	uniformUVecFunctionPointer getUniformFunctionForUVec(glw::GLuint		   argument,
														 const functionObject& function_object) const;

	const glw::GLchar* getUniformName(glw::GLuint argument) const;
	const glw::GLchar* getVaryingName(glw::GLuint argument) const;

	bool isFunctionImplemented(FunctionEnum function, const typeDetails& type) const;

	void logVariableType(const glw::GLvoid* buffer, const glw::GLchar* name, Utils::_variable_type type) const;

	void prepareArgument(const functionObject& function_object, glw::GLuint vertex, glw::GLubyte* buffer);

	void prepareComponents(const functionObject& function_object, glw::GLuint vertex, glw::GLuint argument,
						   glw::GLubyte* buffer);

	void prepareProgram(const functionObject& function_object, Utils::programInfo& program_info);

	void prepareTestData(const functionObject& function_object);
	void prepareVertexShaderCode(const functionObject& function_object);

	bool test(FunctionEnum function, const typeDetails& type);

	void testBegin(const functionObject& function_object, glw::GLuint program_id, glw::GLuint vertex);

	void testInit();

	bool isResultEdgeCase(const functionObject& function_object, glw::GLuint vertex,
						  const Utils::_variable_type result_type, const glw::GLvoid* expected_result_src,
						  const glw::GLvoid* result_src);

	bool verifyResults(const functionObject& function_object, glw::GLuint vertex);

	/* Private constants */
	static const glw::GLdouble m_epsilon;
	static const glw::GLuint   m_n_veritces;

	/* Private fields */
	glw::GLuint m_transform_feedback_buffer_id;
	glw::GLuint m_vertex_array_object_id;

	std::vector<glw::GLubyte> m_expected_results_data;
	FunctionEnum			  m_function;
	TypeDefinition			  m_typeDefinition;
	std::vector<glw::GLubyte> m_argument_data;
	std::string				  m_vertex_shader_code;
};

/* Constants used by BuiltinFunctionTest */
/** Khronos Bug #14010
 *  Using an epsilon value for comparing floating points is error prone.
 *  Rather than writing a new floating point comparison function, I am
 *  increasing the epsilon value to allow greater orders of magnitude
 *  of floating point values.
 **/
const glw::GLdouble BuiltinFunctionTest::m_epsilon	= 0.00002;
const glw::GLuint   BuiltinFunctionTest::m_n_veritces = 1024;

/** Implementations of function objects required by "BuiltinFunctionTest"
 *
 **/
namespace FunctionObject
{
/** Maps variable type with enumeration Utils::_variable_type
 *
 * @tparam T type
 **/
template <typename T>
class typeInfo
{
public:
	static const Utils::_variable_type variable_type =
		TypeHelpers::typeInfo<typename TypeHelpers::referenceToType<T>::result>::variable_type;
};

/** Place data from <in> into <buffer>
 *
 * @param buffer Buffer
 * @param in     Input data
 **/
template <typename T>
class pack
{
public:
	static void set(glw::GLvoid* buffer, const T& in)
	{
		*(T*)buffer = in;
	}
};

/** Place tcu::Matrix data from <in> into <buffer>
 *
 * @param buffer Buffer
 * @param in     Input data
 **/
template <int Cols, int Rows>
class pack<tcu::Matrix<glw::GLdouble, Rows, Cols> >
{
public:
	static void set(glw::GLvoid* buffer, const tcu::Matrix<glw::GLdouble, Rows, Cols>& in)
	{
		glw::GLdouble* data = (glw::GLdouble*)buffer;

		for (glw::GLint column = 0; column < Cols; ++column)
		{
			for (glw::GLint row = 0; row < Rows; ++row)
			{
				glw::GLint index = column * Rows + row;

				data[index] = in(row, column);
			}
		}
	}
};

/** Get data of <out> from <buffer>
 *
 * @param buffer Buffer
 * @param out    Output data
 **/
template <typename T>
class unpack
{
public:
	static void get(const glw::GLvoid* buffer, T& out)
	{
		out = *(T*)buffer;
	}
};

/** Get tcu::Matrix data from <buffer>
 *
 * @param buffer Buffer
 * @param out    Output data
 **/
template <int Cols, int Rows>
class unpack<tcu::Matrix<glw::GLdouble, Rows, Cols> >
{
public:
	static void get(const glw::GLvoid* buffer, tcu::Matrix<glw::GLdouble, Rows, Cols>& out)
	{
		const glw::GLdouble* data = (glw::GLdouble*)buffer;

		for (glw::GLint column = 0; column < Cols; ++column)
		{
			for (glw::GLint row = 0; row < Rows; ++row)
			{
				glw::GLint index = column * Rows + row;

				out(row, column) = data[index];
			}
		}
	}
};

/** Base of unary function classes
 *
 **/
class unaryBase : public BuiltinFunctionTest::functionObject
{
public:
	unaryBase(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
			  const Utils::_variable_type res_type, const Utils::_variable_type arg_type)
		: functionObject(function_enum, function_name, function_pointer, res_type), m_arg_type(arg_type)
	{
	}

	virtual glw::GLuint getArgumentCount() const
	{
		return 1;
	}

	virtual Utils::_variable_type getArgumentType(glw::GLuint /* argument */) const
	{
		return m_arg_type;
	}

protected:
	const Utils::_variable_type m_arg_type;
};

/** Unary function class. It treats input argument as one variable.
 *
 * @tparam ResT Type of result
 * @tparam ArgT Type of argument
 **/
template <typename ResT, typename ArgT>
class unary : public unaryBase
{
public:
	typedef ResT (*functionPointer)(const ArgT&);

	unary(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer)
		: unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
					typeInfo<ArgT>::variable_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		ResT result;
		ArgT arg;

		unpack<ArgT>::get(argument_src, arg);

		functionPointer p_function = (functionPointer)m_p_function;

		result = p_function(arg);

		pack<ResT>::set(result_dst, result);
	}
};

/** Unary function class. It treats input argument as separate components.
 *
 * @tparam ResT Type of result
 **/
template <typename ResT>
class unaryByComponent : public unaryBase
{
public:
	typedef ResT (*functionPointer)(glw::GLdouble);

	unaryByComponent(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer,
					 const Utils::_variable_type res_type, const Utils::_variable_type arg_type)
		: unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		glw::GLuint	n_components = Utils::getNumberOfComponentsForVariableType(m_arg_type);
		ResT*		   p_result		= (ResT*)result_dst;
		glw::GLdouble* p_arg		= (glw::GLdouble*)argument_src;

		functionPointer p_function = (functionPointer)m_p_function;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			p_result[component] = p_function(p_arg[component]);
		}
	}
};

/** Class of functions with one input and one output parameter. It treats arguments as separate components.
 *
 * @tparam ResT Type of result
 * @tparam ArgT Type of argument
 * @tparam OutT Type of output parameter
 **/
template <typename ResT, typename ArgT, typename OutT>
class unaryWithOutputByComponent : public unaryBase
{
public:
	typedef ResT (*functionPointer)(ArgT, OutT&);

	unaryWithOutputByComponent(FunctionEnum function_enum, const glw::GLchar* function_name,
							   functionPointer function_pointer, const Utils::_variable_type res_type,
							   const Utils::_variable_type arg_type, const Utils::_variable_type out_type)
		: unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_type)
		, m_out_type(out_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		ResT* p_result = (ResT*)result_dst;
		OutT* p_out	= (OutT*)((glw::GLubyte*)result_dst + getResultOffset(1));
		ArgT* p_arg	= (ArgT*)argument_src;

		const glw::GLuint n_components_0 = getArgumentComponents(0);
		const glw::GLuint n_components_1 = getResultComponents(1);
		const glw::GLuint n_components   = de::max(n_components_0, n_components_1);

		const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
		const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;

		functionPointer p_function = (functionPointer)m_p_function;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const ArgT first_arg  = p_arg[component * component_step_0];
			OutT&	  second_arg = p_out[component * component_step_1];

			p_result[component] = p_function(first_arg, second_arg);
		}
	}

	glw::GLuint getResultCount() const
	{
		return 2;
	}

	Utils::_variable_type getResultType(glw::GLuint result) const
	{
		Utils::_variable_type type = Utils::VARIABLE_TYPE_UNKNOWN;

		switch (result)
		{
		case 0:
			type = m_res_type;
			break;
		case 1:
			type = m_out_type;
			break;
		default:
			TCU_FAIL("Not implemented");
			break;
		}

		return type;
	}

protected:
	const Utils::_variable_type m_out_type;
};

/** Base of binary function classes.
 *
 **/
class binaryBase : public BuiltinFunctionTest::functionObject
{
public:
	binaryBase(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
			   const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
			   const Utils::_variable_type arg_2_type)
		: functionObject(function_enum, function_name, function_pointer, res_type)
		, m_arg_1_type(arg_1_type)
		, m_arg_2_type(arg_2_type)
	{
	}

	virtual glw::GLuint getArgumentCount() const
	{
		return 2;
	}

	virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const
	{
		switch (argument)
		{
		case 0:
			return m_arg_1_type;
			break;
		case 1:
			return m_arg_2_type;
			break;
		default:
			return Utils::VARIABLE_TYPE_UNKNOWN;
			break;
		}
	}

protected:
	const Utils::_variable_type m_arg_1_type;
	const Utils::_variable_type m_arg_2_type;
};

/** Binary function class. It treats input arguments as two variables.
 *
 * @param ResT  Type of result
 * @param Arg1T Type of first argument
 * @param Arg2T Type of second argument
 **/
template <typename ResT, typename Arg1T, typename Arg2T>
class binary : public binaryBase
{
public:
	typedef ResT (*functionPointer)(const Arg1T&, const Arg2T&);

	binary(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer)
		: binaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
					 typeInfo<Arg1T>::variable_type, typeInfo<Arg2T>::variable_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		const glw::GLuint argument_1_stride = getArgumentStride(0);

		functionPointer p_function = (functionPointer)m_p_function;

		Arg1T arg_1;
		Arg2T arg_2;
		ResT  result;

		unpack<Arg1T>::get(argument_src, arg_1);
		unpack<Arg2T>::get((glw::GLubyte*)argument_src + argument_1_stride, arg_2);

		result = p_function(arg_1, arg_2);

		pack<ResT>::set(result_dst, result);
	}
};

/** Binary function class. It treats input arguments as separate components.
 *
 * @param ResT  Type of result
 * @param Arg1T Type of first argument
 * @param Arg2T Type of second argument
 **/
template <typename ResT, typename Arg1T, typename Arg2T>
class binaryByComponent : public binaryBase
{
public:
	typedef ResT (*functionPointer)(Arg1T, Arg2T);

	binaryByComponent(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer,
					  const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
					  const Utils::_variable_type arg_2_type)
		: binaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_1_type, arg_2_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		ResT*  p_result = (ResT*)result_dst;
		Arg1T* p_arg_1  = (Arg1T*)argument_src;
		Arg2T* p_arg_2  = (Arg2T*)((glw::GLubyte*)argument_src + getArgumentOffset(1));

		const glw::GLuint n_components_0 = getArgumentComponents(0);
		const glw::GLuint n_components_1 = getArgumentComponents(1);
		const glw::GLuint n_components   = de::max(n_components_0, n_components_1);

		const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
		const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;

		functionPointer p_function = (functionPointer)m_p_function;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const Arg1T first_arg  = p_arg_1[component * component_step_0];
			const Arg2T second_arg = p_arg_2[component * component_step_1];

			p_result[component] = p_function(first_arg, second_arg);
		}
	}
};

/** Base of tenary function classes.
 *
 **/
class tenaryBase : public BuiltinFunctionTest::functionObject
{
public:
	tenaryBase(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
			   const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
			   const Utils::_variable_type arg_2_type, const Utils::_variable_type arg_3_type)
		: functionObject(function_enum, function_name, function_pointer, res_type)
		, m_arg_1_type(arg_1_type)
		, m_arg_2_type(arg_2_type)
		, m_arg_3_type(arg_3_type)
	{
	}

	virtual glw::GLuint getArgumentCount() const
	{
		return 3;
	}

	virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const
	{
		switch (argument)
		{
		case 0:
			return m_arg_1_type;
			break;
		case 1:
			return m_arg_2_type;
			break;
		case 2:
			return m_arg_3_type;
			break;
		default:
			return Utils::VARIABLE_TYPE_UNKNOWN;
			break;
		}
	}

protected:
	const Utils::_variable_type m_arg_1_type;
	const Utils::_variable_type m_arg_2_type;
	const Utils::_variable_type m_arg_3_type;
};

/** Tenary function class. It treats input arguments as three variables.
 *
 * @param ResT  Type of result
 * @param Arg1T Type of first argument
 * @param Arg2T Type of second argument
 * @param Arg3T Type of third argument
 **/
template <typename ResT, typename Arg1T, typename Arg2T, typename Arg3T>
class tenary : public tenaryBase
{
public:
	typedef ResT (*functionPointer)(Arg1T, Arg2T, Arg3T);
	typedef typename TypeHelpers::referenceToType<Arg1T>::result arg1T;
	typedef typename TypeHelpers::referenceToType<Arg2T>::result arg2T;
	typedef typename TypeHelpers::referenceToType<Arg3T>::result arg3T;

	tenary(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer)
		: tenaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
					 typeInfo<Arg1T>::variable_type, typeInfo<Arg2T>::variable_type, typeInfo<Arg3T>::variable_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		const glw::GLuint argument_2_offset = getArgumentOffset(1);
		const glw::GLuint argument_3_offset = getArgumentOffset(2);

		functionPointer p_function = (functionPointer)m_p_function;

		arg1T arg_1;
		arg2T arg_2;
		arg3T arg_3;
		ResT  result;

		unpack<arg1T>::get(argument_src, arg_1);
		unpack<arg2T>::get((glw::GLubyte*)argument_src + argument_2_offset, arg_2);
		unpack<arg3T>::get((glw::GLubyte*)argument_src + argument_3_offset, arg_3);

		result = p_function(arg_1, arg_2, arg_3);

		pack<ResT>::set(result_dst, result);
	}
};

/** Tenary function class. It treats input arguments as separate components.
 *

 **/
class tenaryByComponent : public tenaryBase
{
public:
	typedef glw::GLdouble (*functionPointer)(glw::GLdouble, glw::GLdouble, glw::GLdouble);

	tenaryByComponent(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer,
					  const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
					  const Utils::_variable_type arg_2_type, const Utils::_variable_type arg_3_type)
		: tenaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_1_type, arg_2_type,
					 arg_3_type)
	{
	}

	virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
	{
		glw::GLdouble*		 p_result = (glw::GLdouble*)result_dst;
		const glw::GLdouble* p_arg	= (const glw::GLdouble*)argument_src;

		const glw::GLuint n_components_0 = getArgumentComponents(0);
		const glw::GLuint n_components_1 = getArgumentComponents(1);
		const glw::GLuint n_components_2 = getArgumentComponents(2);
		const glw::GLuint n_components   = de::max(de::max(n_components_0, n_components_1), n_components_2);

		const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
		const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
		const glw::GLuint component_step_2 = (1 == n_components_2) ? 0 : 1;

		functionPointer p_function = (functionPointer)m_p_function;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const glw::GLdouble first_arg  = p_arg[component * component_step_0];
			const glw::GLdouble second_arg = p_arg[component * component_step_1 + n_components_0];
			const glw::GLdouble third_arg  = p_arg[component * component_step_2 + n_components_0 + n_components_1];

			p_result[component] = p_function(first_arg, second_arg, third_arg);
		}
	}
};
} /* FunctionObject */

/** Constructor.
 *
 *  @param context Rendering context.
 **/
BuiltinFunctionTest::BuiltinFunctionTest(deqp::Context& context, std::string caseName, FunctionEnum function,
										 TypeDefinition typeDefinition)
	: TestCase(context, caseName.c_str(), "Verify that built-in functions support double-precision types")
	, m_transform_feedback_buffer_id(0)
	, m_vertex_array_object_id(0)
	, m_function(function)
	, m_typeDefinition(typeDefinition)
{
	/* Nothing to be done here */
}

/** Deinitializes all GL objects that may have been created during test execution.
 *
 **/
void BuiltinFunctionTest::deinit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Clean buffers */
	if (0 != m_transform_feedback_buffer_id)
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
		gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
		m_transform_feedback_buffer_id = 0;
	}

	/* Clean VAO */
	if (0 != m_vertex_array_object_id)
	{
		gl.bindVertexArray(0);
		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
		m_vertex_array_object_id = 0;
	}
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult BuiltinFunctionTest::iterate()
{
	/* Check if extension is supported */
	if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
	{
		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
	}

	testInit();

	/* Verify result */
	typeDetails type(m_typeDefinition.n_columns, m_typeDefinition.n_rows);
	if (test(m_function, type))
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	/* Done */
	return tcu::TestNode::STOP;
}

/** Constructor
 *
 * @param function_enum    Function enumeration
 * @param function_name    Function name
 * @param function_pointer Pointer to routine that wiil be executed
 * @param result_type      Type of result
 **/
BuiltinFunctionTest::functionObject::functionObject(FunctionEnum function_enum, const glw::GLchar* function_name,
													glw::GLvoid* function_pointer, Utils::_variable_type result_type)
	: m_function_enum(function_enum)
	, m_function_name(function_name)
	, m_p_function(function_pointer)
	, m_res_type(result_type)
{
	/* Nothing to be done here */
}

/** Get number of components for <argument>
 *
 * @param argument Argument ordinal, starts with 0
 *
 * @return Number of components
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getArgumentComponents(glw::GLuint argument) const
{
	const Utils::_variable_type type		  = getArgumentType(argument);
	const glw::GLuint			n_components  = Utils::getNumberOfComponentsForVariableType(type);

	return n_components;
}

/** Get size in bytes of single component of <argument>
 *
 * @param argument Argument ordinal, starts with 0
 *
 * @return Size of component
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getArgumentComponentSize(glw::GLuint argument) const
{
	const Utils::_variable_type type		   = getArgumentType(argument);
	const Utils::_variable_type base_type	  = Utils::getBaseVariableType(type);
	const glw::GLuint			base_type_size = Utils::getBaseVariableTypeComponentSize(base_type);

	return base_type_size;
}

/** Get offset in bytes of <argument>. 0 is offset of first argument. Assumes tight packing.
 *
 * @param argument Argument ordinal, starts with 0
 *
 * @return Offset of arguemnt's data
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getArgumentOffset(glw::GLuint argument) const
{
	glw::GLuint result = 0;

	for (glw::GLuint i = 0; i < argument; ++i)
	{
		result += getArgumentStride(i);
	}

	return result;
}

/** Get stride in bytes of all arguments
 *
 * @return Stride of all arguments
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getArgumentStride() const
{
	const glw::GLuint n_args = getArgumentCount();
	glw::GLuint		  result = 0;

	for (glw::GLuint i = 0; i < n_args; ++i)
	{
		result += getArgumentStride(i);
	}

	return result;
}

/** Get stride in bytes of <argument>
 *
 * @param argument Argument ordinal, starts with 0
 *
 * @return Stride of argument
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getArgumentStride(glw::GLuint argument) const
{
	const glw::GLuint component_size = getArgumentComponentSize(argument);
	const glw::GLuint n_components   = getArgumentComponents(argument);

	return n_components * component_size;
}

/** Get function enumeration
 *
 * @return Function enumeration
 **/
FunctionEnum BuiltinFunctionTest::functionObject::getFunctionEnum() const
{
	return m_function_enum;
}

/** Get function name
 *
 * @return Function name
 **/
const glw::GLchar* BuiltinFunctionTest::functionObject::getName() const
{
	return m_function_name;
}

/** Get number of components for <result>
 *
 * @param result Result ordinal, starts with 0
 *
 * @return Number of components
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getResultComponents(glw::GLuint result) const
{
	const Utils::_variable_type type		  = getResultType(result);
	const glw::GLuint			n_components  = Utils::getNumberOfComponentsForVariableType(type);

	return n_components;
}

/** Get number of results
 *
 * @return Number of results
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getResultCount() const
{
	return 1;
}

/** Get offset in bytes of <result>. First result offset is 0. Assume tight packing.
 *
 * @param result Result ordinal, starts with 0
 *
 * @return Offset
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getResultOffset(glw::GLuint result) const
{
	glw::GLuint offset = 0;

	for (glw::GLuint i = 0; i < result; ++i)
	{
		offset += getResultStride(i);
		offset = deAlign32(offset, getBaseTypeSize(i));
	}

	return offset;
}

/** Get stride in bytes of <result>.
 *
 * @param result Result ordinal, starts with 0
 *
 * @return Stride
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getResultStride(glw::GLuint result) const
{
	const Utils::_variable_type type		   = getResultType(result);
	const glw::GLuint			n_components   = Utils::getNumberOfComponentsForVariableType(type);

	return n_components * getBaseTypeSize(result);
}

/** Get size in bytes of <result> base component.
 *
 * @param result Result ordinal, starts with 0
 *
 * @return Alignment
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getBaseTypeSize(glw::GLuint result) const
{
	const Utils::_variable_type type		   = getResultType(result);
	const Utils::_variable_type base_type	  = Utils::getBaseVariableType(type);
	const glw::GLuint			base_type_size = Utils::getBaseVariableTypeComponentSize(base_type);

	return base_type_size;
}

/** Get stride in bytes of all results.
 *
 * @return Stride
 **/
glw::GLuint BuiltinFunctionTest::functionObject::getResultStride() const
{
	const glw::GLuint n_results	= getResultCount();
	glw::GLuint		  stride	   = 0;
	glw::GLuint		  maxAlignment = 0;

	for (glw::GLuint i = 0; i < n_results; ++i)
	{
		const glw::GLuint alignment = getBaseTypeSize(i);
		stride += getResultStride(i);
		stride		 = deAlign32(stride, alignment);
		maxAlignment = deMaxu32(maxAlignment, alignment);
	}

	// The stride of all results must also be aligned,
	// so results for next vertex are aligned.
	return deAlign32(stride, maxAlignment);
}

/** Get type of <result>.
 *
 * @param result Result ordinal, starts with 0
 *
 * @return Type
 **/
Utils::_variable_type BuiltinFunctionTest::functionObject::getResultType(glw::GLuint /* result */) const
{
	return m_res_type;
}

/** Constructor
 *
 * @param n_columns Number of columns
 * @param n_rows    Number of rows
 **/
BuiltinFunctionTest::typeDetails::typeDetails(glw::GLuint n_columns, glw::GLuint n_rows)
	: m_n_columns(n_columns), m_n_rows(n_rows)
{
	Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows);
	m_type					   = Utils::getGLDataTypeOfVariableType(type);
	m_type_name				   = Utils::getVariableTypeString(type);

	if (1 == m_n_columns)
	{
		if (1 == m_n_rows)
		{
			m_general_type = SCALAR;
		}
		else
		{
			m_general_type = VECTOR;
		}
	}
	else
	{
		m_general_type = MATRIX;
	}
}

/** Compare two values
 *
 * @param type  Type of values
 * @param left  Pointer to left value
 * @param right Pointer to right value
 *
 * @return true if values are equal, false otherwise
 **/
bool BuiltinFunctionTest::compare(Utils::_variable_type type, const glw::GLvoid* left, const glw::GLvoid* right)
{
	bool result = true;

	const glw::GLuint			n_components = Utils::getNumberOfComponentsForVariableType(type);
	const Utils::_variable_type base_type	= Utils::getBaseVariableType(type);

	switch (base_type)
	{
	case Utils::VARIABLE_TYPE_DOUBLE:

	{
		const glw::GLdouble* left_values  = (glw::GLdouble*)left;
		const glw::GLdouble* right_values = (glw::GLdouble*)right;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const glw::GLdouble left_value  = left_values[component];
			const glw::GLdouble right_value = right_values[component];

			if ((left_value != right_value) && (m_epsilon < de::abs(left_value - right_value)) &&
				(0 == Math::isnan_impl(left_value)) && (0 == Math::isnan_impl(right_value)))
			{
				result = false;
				break;
			}
		}
	}

	break;

	case Utils::VARIABLE_TYPE_INT:

	{
		const glw::GLint* left_values  = (glw::GLint*)left;
		const glw::GLint* right_values = (glw::GLint*)right;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const glw::GLint left_value  = left_values[component];
			const glw::GLint right_value = right_values[component];

			if (left_value != right_value)
			{
				result = false;
				break;
			}
		}
	}

	break;

	case Utils::VARIABLE_TYPE_UINT:

	{
		const glw::GLuint* left_values  = (glw::GLuint*)left;
		const glw::GLuint* right_values = (glw::GLuint*)right;

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const glw::GLuint left_value  = left_values[component];
			const glw::GLuint right_value = right_values[component];

			if (left_value != right_value)
			{
				result = false;
				break;
			}
		}
	}

	break;

	default:

		TCU_FAIL("Not implemented");

		break;
	}

	return result;
}

/** Create instance of function object for given function enumeration and type
 *
 * @param function Function enumeration
 * @param type     Type details
 *
 * @return Create object
 **/
BuiltinFunctionTest::functionObject* BuiltinFunctionTest::getFunctionObject(FunctionEnum	   function,
																			const typeDetails& type)
{
	typedef tcu::Matrix<glw::GLdouble, 2, 2> DMat2;
	typedef tcu::Matrix<glw::GLdouble, 3, 2> DMat2x3;
	typedef tcu::Matrix<glw::GLdouble, 4, 2> DMat2x4;
	typedef tcu::Matrix<glw::GLdouble, 2, 3> DMat3x2;
	typedef tcu::Matrix<glw::GLdouble, 3, 3> DMat3;
	typedef tcu::Matrix<glw::GLdouble, 4, 3> DMat3x4;
	typedef tcu::Matrix<glw::GLdouble, 2, 4> DMat4x2;
	typedef tcu::Matrix<glw::GLdouble, 3, 4> DMat4x3;
	typedef tcu::Matrix<glw::GLdouble, 4, 4> DMat4;

	const glw::GLuint			n_columns	 = type.m_n_columns;
	const glw::GLuint			n_rows		  = type.m_n_rows;
	const Utils::_variable_type scalar_type   = Utils::getDoubleVariableType(1, 1);
	const Utils::_variable_type variable_type = Utils::getDoubleVariableType(n_columns, n_rows);
	const Utils::_variable_type uint_type	 = Utils::getUintVariableType(1, n_rows);
	const Utils::_variable_type int_type	  = Utils::getIntVariableType(1, n_rows);

	switch (function)
	{
	case FUNCTION_ABS:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "abs", de::abs, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_CEIL:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "ceil", ceil, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_CLAMP:

		return new FunctionObject::tenaryByComponent(function, "clamp", Math::clamp, variable_type /* res_type  */,
													 variable_type /* arg1_type */, variable_type /* arg2_type */,
													 variable_type /* arg3_type */);
		break;

	case FUNCTION_CLAMP_AGAINST_SCALAR:

		return new FunctionObject::tenaryByComponent(function, "clamp", Math::clamp, variable_type /* res_type  */,
													 variable_type /* arg1_type */, scalar_type /* arg2_type */,
													 scalar_type /* arg3_type */);
		break;

	case FUNCTION_CROSS:

		return new FunctionObject::binary<tcu::DVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
			function, "cross", tcu::cross);

		break;

	case FUNCTION_DETERMINANT:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DMAT2:
			return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat2 /* ArgT */>(function, "determinant",
																						 Math::determinant);
		case Utils::VARIABLE_TYPE_DMAT3:
			return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat3 /* ArgT */>(function, "determinant",
																						 Math::determinant);
		case Utils::VARIABLE_TYPE_DMAT4:
			return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat4 /* ArgT */>(function, "determinant",
																						 Math::determinant);
		default:
			TCU_FAIL("Not implemented");
			break;
		}

		break;

	case FUNCTION_DISTANCE:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "distance", tcu::distance);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "distance", tcu::distance);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "distance", tcu::distance);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_DOT:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "dot", tcu::dot);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "dot", tcu::dot);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "dot", tcu::dot);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_EQUAL:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "equal", Math::equal);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "equal", Math::equal);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "equal", Math::equal);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_FACEFORWARD:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::tenary<tcu::DVec2 /* ResT */, const tcu::DVec2& /* Arg1T */,
											  const tcu::DVec2& /* Arg2T */, const tcu::DVec2& /* Arg3T */>(
				function, "faceforward", tcu::faceForward);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::tenary<tcu::DVec3 /* ResT */, const tcu::DVec3& /* Arg1T */,
											  const tcu::DVec3& /* Arg2T */, const tcu::DVec3& /* Arg3T */>(
				function, "faceforward", tcu::faceForward);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::tenary<tcu::DVec4 /* ResT */, const tcu::DVec4& /* Arg1T */,
											  const tcu::DVec4& /* Arg2T */, const tcu::DVec4& /* Arg3T */>(
				function, "faceforward", tcu::faceForward);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_FLOOR:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "floor", floor, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_FMA:

		return new FunctionObject::tenaryByComponent(function, "fma", Math::fma, variable_type /* res_type  */,
													 variable_type /* arg1_type */, variable_type /* arg2_type */,
													 variable_type /* arg3_type */);

		break;

	case FUNCTION_FRACT:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "fract", Math::fract, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_FREXP:

		return new FunctionObject::unaryWithOutputByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* ArgT */,
															  glw::GLint /* OutT */>(
			function, "frexp", Math::frexp, variable_type /* res_type */, variable_type /* arg_type */,
			int_type /* out_type */);

		break;

	case FUNCTION_GREATERTHAN:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "greaterThan", Math::greaterThan);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "greaterThan", Math::greaterThan);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "greaterThan", Math::greaterThan);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_GREATERTHANEQUAL:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "greaterThanEqual", Math::greaterThanEqual);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "greaterThanEqual", Math::greaterThanEqual);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "greaterThanEqual", Math::greaterThanEqual);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_INVERSE:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DMAT2:
			return new FunctionObject::unary<DMat2 /* ResT */, DMat2 /* ArgT */>(function, "inverse", Math::inverse);
			break;
		case Utils::VARIABLE_TYPE_DMAT3:
			return new FunctionObject::unary<DMat3 /* ResT */, DMat3 /* ArgT */>(function, "inverse", Math::inverse);
			break;
		case Utils::VARIABLE_TYPE_DMAT4:
			return new FunctionObject::unary<DMat4 /* ResT */, DMat4 /* ArgT */>(function, "inverse", Math::inverse);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_INVERSESQRT:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "inversesqrt", Math::inverseSqrt, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_LDEXP:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLint /* Arg2T */>(
			function, "ldexp", ::ldexp, variable_type /* res_type  */, variable_type /* arg1_type */,
			int_type /* arg2_type */);

		break;

	case FUNCTION_LESSTHAN:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "lessThan", Math::lessThan);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "lessThan", Math::lessThan);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "lessThan", Math::lessThan);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_LESSTHANEQUAL:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "lessThanEqual", Math::lessThanEqual);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "lessThanEqual", Math::lessThanEqual);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "lessThanEqual", Math::lessThanEqual);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_LENGTH:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec2 /* ArgT */>(function, "length",
																							  tcu::length);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec3 /* ArgT */>(function, "length",
																							  tcu::length);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec4 /* ArgT */>(function, "length",
																							  tcu::length);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_MATRIXCOMPMULT:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "matrixCompMult", Math::multiply, variable_type /* res_type  */, variable_type /* arg1_type */,
			variable_type /* arg2_type */);

		break;

	case FUNCTION_MAX:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "max", Math::max, variable_type /* res_type  */, variable_type /* arg1_type */,
			variable_type /* arg2_type */);

		break;

	case FUNCTION_MAX_AGAINST_SCALAR:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "max", Math::max, variable_type /* res_type  */, variable_type /* arg1_type */,
			scalar_type /* arg2_type */);

		break;

	case FUNCTION_MIN:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "min", Math::min, variable_type /* res_type  */, variable_type /* arg1_type */,
			variable_type /* arg2_type */);

		break;

	case FUNCTION_MIN_AGAINST_SCALAR:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "min", Math::min, variable_type /* res_type  */, variable_type /* arg1_type */,
			scalar_type /* arg2_type */);

		break;

	case FUNCTION_MIX:

		return new FunctionObject::tenaryByComponent(function, "mix", Math::mix, variable_type /* res_type  */,
													 variable_type /* arg1_type */, variable_type /* arg2_type */,
													 variable_type /* arg3_type */);

		break;

	case FUNCTION_MOD:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "mod", Math::mod, variable_type /* res_type  */, variable_type /* arg1_type */,
			variable_type /* arg2_type */);

		break;

	case FUNCTION_MOD_AGAINST_SCALAR:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "mod", Math::mod, variable_type /* res_type  */, variable_type /* arg1_type */,
			scalar_type /* arg2_type */);

		break;

	case FUNCTION_MODF:

		return new FunctionObject::unaryWithOutputByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* ArgT */,
															  glw::GLdouble /* OutT */>(
			function, "modf", Math::modf, variable_type /* res_type */, variable_type /* arg_type */,
			variable_type /* out_type */);

		break;

	case FUNCTION_NORMALIZE:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::unary<tcu::DVec2 /* ResT */, tcu::DVec2 /* ArgT */>(function, "normalize",
																						   tcu::normalize);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::unary<tcu::DVec3 /* ResT */, tcu::DVec3 /* ArgT */>(function, "normalize",
																						   tcu::normalize);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::unary<tcu::DVec4 /* ResT */, tcu::DVec4 /* ArgT */>(function, "normalize",
																						   tcu::normalize);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_NOTEQUAL:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "notEqual", Math::notEqual);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "notEqual", Math::notEqual);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "notEqual", Math::notEqual);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_OUTERPRODUCT:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DMAT2:
			return new FunctionObject::binary<DMat2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT2X3:
			return new FunctionObject::binary<DMat2x3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT2X4:
			return new FunctionObject::binary<DMat2x4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT3:
			return new FunctionObject::binary<DMat3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT3X2:
			return new FunctionObject::binary<DMat3x2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT3X4:
			return new FunctionObject::binary<DMat3x4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT4:
			return new FunctionObject::binary<DMat4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT4X2:
			return new FunctionObject::binary<DMat4x2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		case Utils::VARIABLE_TYPE_DMAT4X3:
			return new FunctionObject::binary<DMat4x3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "outerProduct", Math::outerProduct);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_PACKDOUBLE2X32:

		return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::UVec2 /* ArgT */>(function, "packDouble2x32",
																						  Math::packDouble2x32);

		break;

	case FUNCTION_REFLECT:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::binary<tcu::DVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
				function, "reflect", tcu::reflect);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::binary<tcu::DVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
				function, "reflect", tcu::reflect);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::binary<tcu::DVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
				function, "reflect", tcu::reflect);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_REFRACT:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DVEC2:
			return new FunctionObject::tenary<tcu::DVec2 /* ResT */, const tcu::DVec2& /* Arg1T */,
											  const tcu::DVec2& /* Arg2T */, glw::GLdouble /* Arg3T */>(
				function, "refract", tcu::refract);
			break;
		case Utils::VARIABLE_TYPE_DVEC3:
			return new FunctionObject::tenary<tcu::DVec3 /* ResT */, const tcu::DVec3& /* Arg1T */,
											  const tcu::DVec3& /* Arg2T */, glw::GLdouble /* Arg3T */>(
				function, "refract", tcu::refract);
			break;
		case Utils::VARIABLE_TYPE_DVEC4:
			return new FunctionObject::tenary<tcu::DVec4 /* ResT */, const tcu::DVec4& /* Arg1T */,
											  const tcu::DVec4& /* Arg2T */, glw::GLdouble /* Arg3T */>(
				function, "refract", tcu::refract);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_ROUND:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "round", Math::round, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_ROUNDEVEN:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "roundEven", Math::roundEven, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_SIGN:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "sign", Math::sign, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_SMOOTHSTEP:

		return new FunctionObject::tenaryByComponent(function, "smoothstep", Math::smoothStep,
													 variable_type /* res_type  */, variable_type /* arg1_type */,
													 variable_type /* arg2_type */, variable_type /* arg3_type */);

		break;

	case FUNCTION_SMOOTHSTEP_AGAINST_SCALAR:

		return new FunctionObject::tenaryByComponent(function, "smoothstep", Math::smoothStep,
													 variable_type /* res_type  */, scalar_type /* arg1_type */,
													 scalar_type /* arg2_type */, variable_type /* arg3_type */);

		break;

	case FUNCTION_SQRT:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "sqrt", sqrt, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_STEP:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "step", Math::step, variable_type /* res_type  */, variable_type /* arg1_type */,
			variable_type /* arg2_type */);

		break;

	case FUNCTION_STEP_AGAINST_SCALAR:

		return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
													 glw::GLdouble /* Arg2T */>(
			function, "step", Math::step, variable_type /* res_type  */, scalar_type /* arg1_type */,
			variable_type /* arg2_type */);

		break;

	case FUNCTION_TRANSPOSE:

		switch (variable_type)
		{
		case Utils::VARIABLE_TYPE_DMAT2:
			return new FunctionObject::unary<DMat2 /* ResT */, DMat2 /* ArgT */>(function, "transpose",
																				 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT2X3:
			return new FunctionObject::unary<DMat2x3 /* ResT */, DMat3x2 /* ArgT */>(function, "transpose",
																					 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT2X4:
			return new FunctionObject::unary<DMat2x4 /* ResT */, DMat4x2 /* ArgT */>(function, "transpose",
																					 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT3:
			return new FunctionObject::unary<DMat3 /* ResT */, DMat3 /* ArgT */>(function, "transpose",
																				 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT3X2:
			return new FunctionObject::unary<DMat3x2 /* ResT */, DMat2x3 /* ArgT */>(function, "transpose",
																					 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT3X4:
			return new FunctionObject::unary<DMat3x4 /* ResT */, DMat4x3 /* ArgT */>(function, "transpose",
																					 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT4:
			return new FunctionObject::unary<DMat4 /* ResT */, DMat4 /* ArgT */>(function, "transpose",
																				 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT4X2:
			return new FunctionObject::unary<DMat4x2 /* ResT */, DMat2x4 /* ArgT */>(function, "transpose",
																					 Math::transpose);
			break;
		case Utils::VARIABLE_TYPE_DMAT4X3:
			return new FunctionObject::unary<DMat4x3 /* ResT */, DMat3x4 /* ArgT */>(function, "transpose",
																					 Math::transpose);
			break;
		default:
			break;
		}

		break;

	case FUNCTION_TRUNC:

		return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
			function, "trunc", Math::trunc, variable_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_UNPACKDOUBLE2X32:

		return new FunctionObject::unary<tcu::UVec2 /* ResT */, glw::GLdouble /* ArgT */>(function, "unpackDouble2x32",
																						  Math::unpackDouble2x32);

		break;

	case FUNCTION_ISNAN:

		return new FunctionObject::unaryByComponent<glw::GLuint /* ResT */>(
			function, "isnan", Math::isnan_impl, uint_type /* res_type */, variable_type /* arg_type */);

		break;

	case FUNCTION_ISINF:

		return new FunctionObject::unaryByComponent<glw::GLuint /* ResT */>(
			function, "isinf", Math::isinf_impl, uint_type /* res_type */, variable_type /* arg_type */);

		break;

	default:
		TCU_FAIL("Not implemented");
		return 0;
		break;
	}

	TCU_FAIL("Not implemented");
	return 0;
}

/** Get gl.uniform* that match type of argument. Assumes that type is matrix of double.
 *
 * @param argument        Argument index
 * @param function_object Function object
 *
 * @return Function pointer
 **/
BuiltinFunctionTest::uniformDMatFunctionPointer BuiltinFunctionTest::getUniformFunctionForDMat(
	glw::GLuint argument, const functionObject& function_object) const
{
	const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
	const glw::Functions&		gl			  = m_context.getRenderContext().getFunctions();

	switch (argument_type)
	{
	case Utils::VARIABLE_TYPE_DMAT2:
		return gl.uniformMatrix2dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT2X3:
		return gl.uniformMatrix2x3dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT2X4:
		return gl.uniformMatrix2x4dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT3:
		return gl.uniformMatrix3dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT3X2:
		return gl.uniformMatrix3x2dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT3X4:
		return gl.uniformMatrix3x4dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT4:
		return gl.uniformMatrix4dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT4X2:
		return gl.uniformMatrix4x2dv;
		break;
	case Utils::VARIABLE_TYPE_DMAT4X3:
		return gl.uniformMatrix4x3dv;
		break;
	default:
		break;
	}

	TCU_FAIL("Not implemented");
	return 0;
}

/** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of double.
 *
 * @param argument        Argument index
 * @param function_object Function object
 *
 * @return Function pointer
 **/
BuiltinFunctionTest::uniformDVecFunctionPointer BuiltinFunctionTest::getUniformFunctionForDVec(
	glw::GLuint argument, const functionObject& function_object) const
{
	const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
	const glw::Functions&		gl			  = m_context.getRenderContext().getFunctions();

	switch (argument_type)
	{
	case Utils::VARIABLE_TYPE_DOUBLE:
		return gl.uniform1dv;
		break;
	case Utils::VARIABLE_TYPE_DVEC2:
		return gl.uniform2dv;
		break;
	case Utils::VARIABLE_TYPE_DVEC3:
		return gl.uniform3dv;
		break;
	case Utils::VARIABLE_TYPE_DVEC4:
		return gl.uniform4dv;
		break;
	default:
		TCU_FAIL("Not implemented");
		break;
	}

	return 0;
}

/** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of signed integer.
 *
 * @param argument        Argument index
 * @param function_object Function object
 *
 * @return Function pointer
 **/
BuiltinFunctionTest::uniformIVecFunctionPointer BuiltinFunctionTest::getUniformFunctionForIVec(
	glw::GLuint argument, const functionObject& function_object) const
{
	const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
	const glw::Functions&		gl			  = m_context.getRenderContext().getFunctions();

	switch (argument_type)
	{
	case Utils::VARIABLE_TYPE_INT:
		return gl.uniform1iv;
		break;
	case Utils::VARIABLE_TYPE_IVEC2:
		return gl.uniform2iv;
		break;
	case Utils::VARIABLE_TYPE_IVEC3:
		return gl.uniform3iv;
		break;
	case Utils::VARIABLE_TYPE_IVEC4:
		return gl.uniform4iv;
		break;
	default:
		TCU_FAIL("Not implemented");
		break;
	}

	return 0;
}

/** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of unsigned integer.
 *
 * @param argument        Argument index
 * @param function_object Function object
 *
 * @return Function pointer
 **/
BuiltinFunctionTest::uniformUVecFunctionPointer BuiltinFunctionTest::getUniformFunctionForUVec(
	glw::GLuint argument, const functionObject& function_object) const
{
	const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
	const glw::Functions&		gl			  = m_context.getRenderContext().getFunctions();

	switch (argument_type)
	{
	case Utils::VARIABLE_TYPE_UVEC2:
		return gl.uniform2uiv;
		break;
	default:
		TCU_FAIL("Not implemented");
		break;
	}

	return 0;
}

/** Get name of uniform that will be used as <argument>.
 *
 * @param argument Argument index
 *
 * @return Name of uniform
 **/
const glw::GLchar* BuiltinFunctionTest::getUniformName(glw::GLuint argument) const
{
	switch (argument)
	{
	case 0:
		return "uniform_0";
		break;
	case 1:
		return "uniform_1";
		break;
	case 2:
		return "uniform_2";
		break;
	default:
		TCU_FAIL("Not implemented");
		return 0;
		break;
	}
}

/** Get name of varying that will be used as <result>.
 *
 * @param result Result index
 *
 * @return Name of varying
 **/
const glw::GLchar* BuiltinFunctionTest::getVaryingName(glw::GLuint result) const
{
	switch (result)
	{
	case 0:
		return "result_0";
		break;
	case 1:
		return "result_1";
		break;
	case 2:
		return "result_2";
		break;
	default:
		TCU_FAIL("Not implemented");
		return 0;
		break;
	}
}

/** Check if given combination of function and type is implemented
 *
 * @param function Function enumeration
 * @param type     Type details
 *
 * @return true if function is available for given type, false otherwise
 **/
bool BuiltinFunctionTest::isFunctionImplemented(FunctionEnum function, const typeDetails& type) const
{
	static const bool look_up_table[][3] = {
		/* SCALAR, VECTOR, MATRIX */
		/* FUNCTION_ABS:                       */ { true, true, false },
		/* FUNCTION_CEIL:                      */ { true, true, false },
		/* FUNCTION_CLAMP:                     */ { true, true, false },
		/* FUNCTION_CLAMP_AGAINST_SCALAR:      */ { false, true, false },
		/* FUNCTION_CROSS:                     */ { false, true, false },
		/* FUNCTION_DETERMINANT:               */ { false, false, true },
		/* FUNCTION_DISTANCE:                  */ { false, true, false },
		/* FUNCTION_DOT:                       */ { false, true, false },
		/* FUNCTION_EQUAL:                     */ { false, true, false },
		/* FUNCTION_FACEFORWARD:               */ { false, true, false },
		/* FUNCTION_FLOOR:                     */ { true, true, false },
		/* FUNCTION_FMA:                       */ { true, true, false },
		/* FUNCTION_FRACT:                     */ { true, true, false },
		/* FUNCTION_FREXP:                     */ { true, true, false },
		/* FUNCTION_GREATERTHAN:               */ { false, true, false },
		/* FUNCTION_GREATERTHANEQUAL:          */ { false, true, false },
		/* FUNCTION_INVERSE:                   */ { false, false, true },
		/* FUNCTION_INVERSESQRT:               */ { true, true, false },
		/* FUNCTION_LDEXP:                     */ { true, true, false },
		/* FUNCTION_LESSTHAN:                  */ { false, true, false },
		/* FUNCTION_LESSTHANEQUAL:             */ { false, true, false },
		/* FUNCTION_LENGTH:                    */ { false, true, false },
		/* FUNCTION_MATRIXCOMPMULT:            */ { false, false, true },
		/* FUNCTION_MAX:                       */ { true, true, false },
		/* FUNCTION_MAX_AGAINST_SCALAR:        */ { false, true, false },
		/* FUNCTION_MIN:                       */ { true, true, false },
		/* FUNCTION_MIN_AGAINST_SCALAR:        */ { false, true, false },
		/* FUNCTION_MIX:                       */ { true, true, false },
		/* FUNCTION_MOD:                       */ { true, true, false },
		/* FUNCTION_MOD_AGAINST_SCALAR:        */ { false, true, false },
		/* FUNCTION_MODF:                      */ { true, true, false },
		/* FUNCTION_NORMALIZE:                 */ { false, true, false },
		/* FUNCTION_NOTEQUAL:                  */ { false, true, false },
		/* FUNCTION_OUTERPRODUCT:              */ { false, false, true },
		/* FUNCTION_PACKDOUBLE2X32:            */ { true, false, false },
		/* FUNCTION_REFLECT:                   */ { false, true, false },
		/* FUNCTION_REFRACT:                   */ { false, true, false },
		/* FUNCTION_ROUND:                     */ { true, true, false },
		/* FUNCTION_ROUNDEVEN:                 */ { true, true, false },
		/* FUNCTION_SIGN:                      */ { true, false, false },
		/* FUNCTION_SMOOTHSTEP:                */ { true, true, false },
		/* FUNCTION_SMOOTHSTEP_AGAINST_SCALAR: */ { false, true, false },
		/* FUNCTION_SQRT:                      */ { true, true, false },
		/* FUNCTION_STEP:                      */ { true, true, false },
		/* FUNCTION_STEP_AGAINST_SCALAR:       */ { false, true, false },
		/* FUNCTION_TRANSPOSE:                 */ { false, false, false },
		/* FUNCTION_TRUNC:                     */ { true, true, false },
		/* FUNCTION_UNPACKDOUBLE2X32:          */ { true, false, false },
		/* FUNCTION_ISNAN:                     */ { true, true, false },
		/* FUNCTION_ISINF:                     */ { true, true, false },
	};

	bool result = look_up_table[function][type.m_general_type];

	if (true == result)
	{
		switch (function)
		{
		case FUNCTION_CROSS: /* Only 3 element vectors */
			result = (3 == type.m_n_rows);
			break;
		case FUNCTION_DETERMINANT: /* Only square matrices */
		case FUNCTION_INVERSE:
			result = (type.m_n_columns == type.m_n_rows);
			break;
		default:
			break;
		}
	}

	return result;
}

/** Logs variable of given type: name (type) [values]
 *
 * @param buffer Source of data
 * @param name   Name of variable
 * @param type   Type of variable
 **/
void BuiltinFunctionTest::logVariableType(const glw::GLvoid* buffer, const glw::GLchar* name,
										  Utils::_variable_type type) const
{
	const Utils::_variable_type base_type	= Utils::getBaseVariableType(type);
	const glw::GLuint			n_components = Utils::getNumberOfComponentsForVariableType(type);
	tcu::MessageBuilder			message		 = m_context.getTestContext().getLog() << tcu::TestLog::Message;

	message << name << " (" << Utils::getVariableTypeString(type) << ") [";

	for (glw::GLuint component = 0; component < n_components; ++component)
	{
		if (0 != component)
		{
			message << ", ";
		}

		switch (base_type)
		{
		case Utils::VARIABLE_TYPE_DOUBLE:
			message << ((glw::GLdouble*)buffer)[component];
			break;
		case Utils::VARIABLE_TYPE_INT:
			message << ((glw::GLint*)buffer)[component];
			break;
		case Utils::VARIABLE_TYPE_UINT:
			message << ((glw::GLuint*)buffer)[component];
			break;
		default:
			TCU_FAIL("Not implemented");
		}
	}

	message << "]" << tcu::TestLog::EndMessage;
}

/** Prepare input arguments, data are stored in <buffer>
 *
 * @param function_object Function object
 * @param vertex          Vertex index
 * @param buffer          Buffer pointer
 **/
void BuiltinFunctionTest::prepareArgument(const functionObject& function_object, glw::GLuint vertex,
										  glw::GLubyte* buffer)
{
	const glw::GLuint n_arguments = function_object.getArgumentCount();

	for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
	{
		const glw::GLuint offset = function_object.getArgumentOffset(argument);

		prepareComponents(function_object, vertex, argument, buffer + offset);
	}
}

/** Prepare components for given <function_object>, <vertex> and <argument>
 *
 * @param function_object Function object
 * @param vertex          Vertex index
 * @param argument        Argument index
 * @param buffer          Buffer pointer
 **/
void BuiltinFunctionTest::prepareComponents(const functionObject& function_object, glw::GLuint vertex,
											glw::GLuint argument, glw::GLubyte* buffer)
{
	glw::GLuint					argument_index[3]		 = { 0 };
	glw::GLuint					argument_reset[3]		 = { 0 };
	glw::GLuint					argument_step[3]		 = { 0 };
	glw::GLdouble				double_argument_start[3] = { 0.0 };
	const Utils::_variable_type base_arg_type = Utils::getBaseVariableType(function_object.getArgumentType(argument));
	glw::GLuint					int_argument_start  = -4;
	const glw::GLuint			n_arguments			= function_object.getArgumentCount();
	const glw::GLuint			n_components		= function_object.getArgumentComponents(argument);
	glw::GLuint					uint_argument_start = 0;

	switch (n_arguments)
	{
	case 1:
		argument_step[0]		 = 1;
		argument_reset[0]		 = 1024;
		double_argument_start[0] = -511.5;
		break;
	case 2:
		argument_step[0]		 = 32;
		argument_step[1]		 = 1;
		argument_reset[0]		 = 32;
		argument_reset[1]		 = 32;
		double_argument_start[0] = -15.5;
		double_argument_start[1] = -15.5;
		break;
	case 3:
		argument_step[0]		 = 64;
		argument_step[1]		 = 8;
		argument_step[2]		 = 1;
		argument_reset[0]		 = 16;
		argument_reset[1]		 = 8;
		argument_reset[2]		 = 8;
		double_argument_start[0] = -7.5;
		double_argument_start[1] = -3.5;
		double_argument_start[2] = -3.5;
		break;
	default:
		TCU_FAIL("Not implemented");
		return;
		break;
	};

	switch (function_object.getFunctionEnum())
	{
	case FUNCTION_CLAMP: /* arg_2 must be less than arg_3 */
	case FUNCTION_CLAMP_AGAINST_SCALAR:
		double_argument_start[2] = 4.5;
		break;
	case FUNCTION_INVERSESQRT: /* inversesqrt is undefined for argument <= 0 */
		double_argument_start[0] = 16.5;
		break;
	case FUNCTION_SMOOTHSTEP: /* arg_1 must be less than arg_2 */
	case FUNCTION_SMOOTHSTEP_AGAINST_SCALAR:
		argument_step[0]		 = 1;
		argument_step[1]		 = 8;
		argument_step[2]		 = 64;
		argument_reset[0]		 = 8;
		argument_reset[1]		 = 8;
		argument_reset[2]		 = 16;
		double_argument_start[0] = -3.5;
		double_argument_start[1] = 4.5;
		double_argument_start[2] = -7.5;
		break;
	default:
		break;
	}

	for (glw::GLuint i = 0; i < n_arguments; ++i)
	{
		argument_index[i] = (vertex / argument_step[i]) % argument_reset[i];
	}

	switch (base_arg_type)
	{
	case Utils::VARIABLE_TYPE_DOUBLE:
	{
		glw::GLdouble* argument_dst = (glw::GLdouble*)buffer;

		double_argument_start[argument] += argument_index[argument];

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			glw::GLdouble value = double_argument_start[argument] + ((glw::GLdouble)component) / 8.0;

			switch (function_object.getFunctionEnum())
			{
			case FUNCTION_ROUND: /* Result for 0.5 depends on implementation */
				if (0.5 == Math::fract(value))
				{
					value += 0.01;
				}
				break;
			default:
				break;
			}

			argument_dst[component] = value;
		}
	}
	break;
	case Utils::VARIABLE_TYPE_INT:
	{
		glw::GLint* argument_dst = (glw::GLint*)buffer;

		uint_argument_start += argument_index[argument];

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const glw::GLint value = int_argument_start + component;

			argument_dst[component] = value;
		}
	}
	break;
	case Utils::VARIABLE_TYPE_UINT:
	{
		glw::GLuint* argument_dst = (glw::GLuint*)buffer;

		uint_argument_start += argument_index[argument];

		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			const glw::GLuint value = uint_argument_start + component;

			argument_dst[component] = value;
		}
	}
	break;
	default:
		TCU_FAIL("Not implemented");
		return;
		break;
	}
}

/** Prepare programInfo for given functionObject
 *
 * @param function_object  Function object
 * @param out_program_info Program info
 **/
void BuiltinFunctionTest::prepareProgram(const functionObject& function_object, Utils::programInfo& out_program_info)
{
	const glw::GLuint		  n_varying_names  = function_object.getResultCount();
	static const glw::GLchar* varying_names[3] = { getVaryingName(0), getVaryingName(1), getVaryingName(2) };

	prepareVertexShaderCode(function_object);

	out_program_info.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* tes */, m_vertex_shader_code.c_str(),
						   varying_names, n_varying_names);
}

/** Prepare input data and expected results for given function object
 *
 * @param function_object Function object
 **/
void BuiltinFunctionTest::prepareTestData(const functionObject& function_object)
{
	const glw::GLuint result_stride		   = function_object.getResultStride();
	const glw::GLuint result_buffer_size   = result_stride * m_n_veritces;
	const glw::GLuint argument_stride	  = function_object.getArgumentStride();
	const glw::GLuint argument_buffer_size = m_n_veritces * argument_stride;

	m_argument_data.clear();
	m_expected_results_data.clear();

	m_argument_data.resize(argument_buffer_size);
	m_expected_results_data.resize(result_buffer_size);

	for (glw::GLuint vertex = 0; vertex < m_n_veritces; ++vertex)
	{
		const glw::GLuint result_offset   = vertex * result_stride;
		glw::GLdouble*	result_dst	  = (glw::GLdouble*)&m_expected_results_data[result_offset];
		const glw::GLuint argument_offset = vertex * argument_stride;
		glw::GLubyte*	 argument_dst	= &m_argument_data[argument_offset];

		prepareArgument(function_object, vertex, argument_dst);
		function_object.call(result_dst, argument_dst);
	}
}

/** Prepare source code of vertex shader for given function object. Result is stored in m_vertex_shader_code.
 *
 * @param function_object Function object
 **/
void BuiltinFunctionTest::prepareVertexShaderCode(const functionObject& function_object)
{
	static const glw::GLchar* shader_template_code = "#version 400 core\n"
													 "\n"
													 "precision highp float;\n"
													 "\n"
													 "ARGUMENT_DEFINITION"
													 "\n"
													 "RESULT_DEFINITION"
													 "\n"
													 "void main()\n"
													 "{\n"
													 "    RESULT_NAME = RESULT_TYPE(FUNCTION_NAME(ARGUMENT));\n"
													 "}\n"
													 "\n";

	static const glw::GLchar* argument_definition_token = "ARGUMENT_DEFINITION";
	static const glw::GLchar* argument_token			= "ARGUMENT";
	static const glw::GLchar* function_name_token		= "FUNCTION_NAME";
	static const glw::GLchar* result_definition_token   = "RESULT_DEFINITION";
	static const glw::GLchar* result_name_token			= "RESULT_NAME";
	static const glw::GLchar* result_type_token			= "RESULT_TYPE";
	static const glw::GLchar* uniform_name_token		= "UNIFORM_NAME";
	static const glw::GLchar* uniform_type_token		= "UNIFORM_TYPE";

	static const glw::GLchar* argument_definition = "uniform UNIFORM_TYPE UNIFORM_NAME;\nARGUMENT_DEFINITION";
	static const glw::GLchar* argument_str		  = ", UNIFORM_NAMEARGUMENT";
	static const glw::GLchar* first_argument	  = "UNIFORM_NAMEARGUMENT";
	static const glw::GLchar* result_definition   = "flat out RESULT_TYPE RESULT_NAME;\nRESULT_DEFINITION";

	const glw::GLuint argument_definition_length = (glw::GLuint)strlen(argument_definition);
	const glw::GLuint first_argument_length		 = (glw::GLuint)strlen(first_argument);
	const glw::GLuint n_arguments				 = function_object.getArgumentCount();
	const glw::GLuint n_results					 = function_object.getResultCount();
	const glw::GLuint result_definition_length   = (glw::GLuint)strlen(result_definition);
	std::string		  result_type				 = Utils::getVariableTypeString(function_object.getResultType(0));

	size_t		search_position = 0;
	std::string string			= shader_template_code;

	/* Replace ARGUMENT_DEFINITION with definitions */
	for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
	{
		Utils::_variable_type argument_type = function_object.getArgumentType(argument);
		const glw::GLchar*	uniform_name  = getUniformName(argument);
		std::string			  uniform_type  = Utils::getVariableTypeString(argument_type);

		Utils::replaceToken(argument_definition_token, search_position, argument_definition, string);

		search_position -= argument_definition_length;

		Utils::replaceToken(uniform_type_token, search_position, uniform_type.c_str(), string);
		Utils::replaceToken(uniform_name_token, search_position, uniform_name, string);
	}

	/* Remove ARGUMENT_DEFINITION */
	Utils::replaceToken(argument_definition_token, search_position, "", string);

	/* Replace RESULT_DEFINITION with definitions */
	for (glw::GLuint result = 0; result < n_results; ++result)
	{
		Utils::_variable_type variable_type = function_object.getResultType(result);
		const glw::GLchar*	varying_name  = getVaryingName(result);
		std::string			  varying_type  = Utils::getVariableTypeString(variable_type);

		Utils::replaceToken(result_definition_token, search_position, result_definition, string);

		search_position -= result_definition_length;

		Utils::replaceToken(result_type_token, search_position, varying_type.c_str(), string);
		Utils::replaceToken(result_name_token, search_position, varying_name, string);
	}

	/* Remove RESULT_DEFINITION */
	Utils::replaceToken(result_definition_token, search_position, "", string);

	/* Replace RESULT_NAME */
	Utils::replaceToken(result_name_token, search_position, getVaryingName(0), string);

	/* Replace RESULT_TYPE */
	Utils::replaceToken(result_type_token, search_position, result_type.c_str(), string);

	/* Replace FUNCTION_NAME */
	Utils::replaceToken(function_name_token, search_position, function_object.getName(), string);

	/* Replace ARGUMENT with list of arguments */
	for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
	{
		const glw::GLchar* uniform_name = getUniformName(argument);

		if (0 == argument)
		{
			Utils::replaceToken(argument_token, search_position, first_argument, string);
		}
		else
		{
			Utils::replaceToken(argument_token, search_position, argument_str, string);
		}

		search_position -= first_argument_length;

		Utils::replaceToken(uniform_name_token, search_position, uniform_name, string);
	}

	for (glw::GLuint result = 1; result < n_results; ++result)
	{
		const glw::GLchar* varying_name = getVaryingName(result);

		Utils::replaceToken(argument_token, search_position, argument_str, string);

		search_position -= first_argument_length;

		Utils::replaceToken(uniform_name_token, search_position, varying_name, string);
	}

	/* Remove ARGUMENT */
	Utils::replaceToken(argument_token, search_position, "", string);

	m_vertex_shader_code = string;
}

/** Test single function with one type
 *
 * param function Function enumeration
 * param type     Type details
 *
 * @return true if test pass (or function is not available for <type>), false otherwise
 **/
bool BuiltinFunctionTest::test(FunctionEnum function, const typeDetails& type)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Skip if function is not implemented for type */
	if (false == isFunctionImplemented(function, type))
	{
		return true;
	}

	Utils::programInfo			  program(m_context);
	de::UniquePtr<functionObject> function_object(getFunctionObject(function, type));

	prepareProgram(*function_object, program);
	prepareTestData(*function_object);

	/* Set up program */
	gl.useProgram(program.m_program_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");

	for (glw::GLuint vertex = 0; vertex < m_n_veritces; ++vertex)
	{
		testBegin(*function_object, program.m_program_object_id, vertex);

		gl.beginTransformFeedback(GL_POINTS);
		GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");

		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");

		gl.endTransformFeedback();
		GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");

		if (false == verifyResults(*function_object, vertex))
		{
			return false;
		}
	}

	return true;
}

/** Update transform feedback buffer and uniforms
 *
 * @param function_object Function object
 * @param program_id      Program object id
 * @param vertex          Vertex index
 **/
void BuiltinFunctionTest::testBegin(const functionObject& function_object, glw::GLuint program_id, glw::GLuint vertex)
{
	const glw::GLuint	 arguments_stride   = function_object.getArgumentStride();
	const glw::Functions& gl				 = m_context.getRenderContext().getFunctions();
	const glw::GLuint	 n_arguments		 = function_object.getArgumentCount();
	const glw::GLuint	 result_buffer_size = function_object.getResultStride();
	const glw::GLuint	 vertex_offset		 = arguments_stride * vertex;

	/* Update transform feedback buffer */
	std::vector<glw::GLubyte> transform_feedback_buffer_data;
	transform_feedback_buffer_data.resize(result_buffer_size);

	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, result_buffer_size, &transform_feedback_buffer_data[0],
				  GL_DYNAMIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");

	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */,
					   result_buffer_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");

	/* Update VAO */
	gl.bindVertexArray(m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");

	for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
	{
		const glw::GLuint			argument_offset  = function_object.getArgumentOffset(argument);
		const Utils::_variable_type argument_type	= function_object.getArgumentType(argument);
		const glw::GLuint			n_columns		 = Utils::getNumberOfColumnsForVariableType(argument_type);
		const glw::GLchar*			uniform_name	 = getUniformName(argument);
		const glw::GLint			uniform_location = gl.getUniformLocation(program_id, uniform_name);
		const glw::GLdouble*		uniform_src = (glw::GLdouble*)&m_argument_data[vertex_offset + argument_offset];

		GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");

		if (-1 == uniform_location)
		{
			TCU_FAIL("Inactive uniform");
		}

		if (1 == n_columns)
		{
			switch (Utils::getBaseVariableType(argument_type))
			{
			case Utils::VARIABLE_TYPE_DOUBLE:
			{
				uniformDVecFunctionPointer p_uniform_function = getUniformFunctionForDVec(argument, function_object);

				p_uniform_function(uniform_location, 1 /* count */, uniform_src);
			}
			break;
			case Utils::VARIABLE_TYPE_UINT:
			{
				uniformUVecFunctionPointer p_uniform_function = getUniformFunctionForUVec(argument, function_object);

				p_uniform_function(uniform_location, 1 /* count */, (glw::GLuint*)uniform_src);
			}
			break;
			case Utils::VARIABLE_TYPE_INT:
			{
				uniformIVecFunctionPointer p_uniform_function = getUniformFunctionForIVec(argument, function_object);

				p_uniform_function(uniform_location, 1 /* count */, (glw::GLint*)uniform_src);
			}
			break;
			default:
				TCU_FAIL("Not implemented");
				break;
			}
		}
		else
		{
			uniformDMatFunctionPointer p_uniform_function = getUniformFunctionForDMat(argument, function_object);

			p_uniform_function(uniform_location, 1 /* count */, GL_FALSE /* transpose */, uniform_src);
		}
	}
}

/** Init GL obejcts
 *
 **/
void BuiltinFunctionTest::testInit()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genBuffers(1, &m_transform_feedback_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");

	gl.genVertexArrays(1, &m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");

	gl.enable(GL_RASTERIZER_DISCARD);
}

/** Checks if function result is an acceptable edge case
 *
 * @param function_object Function object
 * @param vertex          Vertex index
 *
 * @return true if all results are as expected, false otherwise
 **/
bool BuiltinFunctionTest::isResultEdgeCase(const functionObject& function_object, glw::GLuint vertex,
										   const Utils::_variable_type result_type,
										   const glw::GLvoid* expected_result_src, const glw::GLvoid* result_src)
{
	FunctionEnum function_type = function_object.getFunctionEnum();
	switch (function_type)
	{
	// mod(a, b) is defined as a - b * floor(a/b) and mod(a,a) should be 0. However OpenGL
	// allows for some error in division, so a/a could actually end up being 1.0 - 1ULP.
	// In such a case, floor(a/a) would end up as 0, with mod(a,a) becoming a.
	case FUNCTION_MOD:
	case FUNCTION_MOD_AGAINST_SCALAR:
	{
		const glw::GLuint	arguments_stride   = function_object.getArgumentStride();
		const glw::GLuint	vertex_offset	   = arguments_stride * vertex;
		const glw::GLuint	argument_1_offset  = function_object.getArgumentOffset(0);
		const glw::GLuint	argument_2_offset  = function_object.getArgumentOffset(1);
		const glw::GLuint	argument_1_index   = argument_1_offset + vertex_offset;
		const glw::GLuint	argument_2_index   = argument_2_offset + vertex_offset;
		const glw::GLubyte*  argument_1_bytes  = &m_argument_data[argument_1_index];
		const glw::GLubyte*  argument_2_bytes  = &m_argument_data[argument_2_index];
		const glw::GLdouble* argument_1		   = reinterpret_cast<const glw::GLdouble*>(argument_1_bytes);
		const glw::GLdouble* argument_2		   = reinterpret_cast<const glw::GLdouble*>(argument_2_bytes);
		const glw::GLdouble* expected_result   = reinterpret_cast<const glw::GLdouble*>(expected_result_src);
		const glw::GLdouble* actual_result	   = reinterpret_cast<const glw::GLdouble*>(result_src);
		bool				 edge_case_present = false;
		bool				 recheck		   = false;

		// verify if there is a mod(a, a) case and prepare new expected result
		const glw::GLuint		   n_components = Utils::getNumberOfComponentsForVariableType(result_type);
		std::vector<glw::GLdouble> corrected_expected_result(n_components, 0.0);
		for (glw::GLuint component = 0; component < n_components; ++component)
		{
			glw::GLdouble expected_result_component = expected_result[component];
			glw::GLdouble actual_result_component   = actual_result[component];
			glw::GLdouble argument_1_component		= argument_1[component];
			glw::GLdouble argument_2_component		= argument_2[(function_type == FUNCTION_MOD) ? component : 0];

			// if coresponding components of arguments are equal and if component of first argument
			// and component of result are equal then expected result must be corrected
			edge_case_present = (m_epsilon > de::abs(argument_1_component - argument_2_component)) &&
								(m_epsilon > de::abs(argument_1_component - actual_result_component));
			recheck |= edge_case_present;
			corrected_expected_result[component] = edge_case_present ? argument_1_component : expected_result_component;
		}

		// recheck test result with corrected expected result
		return (recheck && compare(result_type, &(corrected_expected_result[0]), result_src));
	}
	default:
		return false;
	}
}

/** Compare contents of transform feedback buffer with expected results
 *
 * @param function_object Function object
 * @param vertex          Vertex index
 *
 * @return true if all results are as expected, false otherwise
 **/
bool BuiltinFunctionTest::verifyResults(const functionObject& function_object, glw::GLuint vertex)
{
	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
	bool				  test_result	  = true;
	const glw::GLuint	 n_results		   = function_object.getResultCount();
	const glw::GLuint	 results_stride   = function_object.getResultStride();
	const glw::GLuint	 results_offset   = vertex * results_stride;
	const glw::GLubyte*   expected_results = &m_expected_results_data[results_offset];

	/* Get transform feedback data */
	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");

	glw::GLubyte* feedback_data = (glw::GLubyte*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");

	for (glw::GLuint result = 0; result < n_results; ++result)
	{
		const Utils::_variable_type result_type   = function_object.getResultType(result);
		const glw::GLuint			result_offset = function_object.getResultOffset(result);

		const glw::GLvoid* expected_result_src = expected_results + result_offset;
		const glw::GLvoid* result_src		   = feedback_data + result_offset;

		if (compare(result_type, expected_result_src, result_src))
			continue;

		if (!isResultEdgeCase(function_object, vertex, result_type, expected_result_src, result_src))
		{
			test_result = false;
			break;
		}
	}

	/* Unmap transform feedback buffer */
	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");

	if (false == test_result)
	{
		const glw::GLuint argument_stride  = function_object.getArgumentStride();
		const glw::GLuint arguments_offset = vertex * argument_stride;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
											<< tcu::TestLog::EndMessage;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function: " << function_object.getName()
											<< tcu::TestLog::EndMessage;

		for (glw::GLuint result = 0; result < n_results; ++result)
		{
			const Utils::_variable_type result_type   = function_object.getResultType(result);
			const glw::GLuint			result_offset = function_object.getResultOffset(result);

			const glw::GLvoid* expected_result_src = expected_results + result_offset;
			const glw::GLvoid* result_src		   = feedback_data + result_offset;

			logVariableType(result_src, "Result", result_type);
			logVariableType(expected_result_src, "Expected result", result_type);
		}

		for (glw::GLuint argument = 0; argument < function_object.getArgumentCount(); ++argument)
		{
			const glw::GLuint   argument_offset = function_object.getArgumentOffset(argument);
			const glw::GLubyte* argument_src	= &m_argument_data[arguments_offset + argument_offset];

			logVariableType(argument_src, "Argument", function_object.getArgumentType(argument));
		}

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader:\n"
											<< m_vertex_shader_code << tcu::TestLog::EndMessage;
	}

	return test_result;
}

/** Constructor.
 *
 *  @param context Rendering context.
 **/
GPUShaderFP64Tests::GPUShaderFP64Tests(deqp::Context& context)
	: TestCaseGroup(context, "gpu_shader_fp64", "Verifies \"gpu_shader_fp64\" functionality")
{
	/* Left blank on purpose */
}

/** Initializes a texture_storage_multisample test group.
 *
 **/
void GPUShaderFP64Tests::init(void)
{
	TestCaseGroup* fp64 = new TestCaseGroup(m_context, "fp64", "");
	fp64->addChild(new GPUShaderFP64Test1(m_context));
	fp64->addChild(new GPUShaderFP64Test2(m_context));
	fp64->addChild(new GPUShaderFP64Test3(m_context));
	fp64->addChild(new GPUShaderFP64Test4(m_context));
	fp64->addChild(new GPUShaderFP64Test5(m_context));
	fp64->addChild(new GPUShaderFP64Test6(m_context));
	fp64->addChild(new GPUShaderFP64Test7(m_context));
	fp64->addChild(new GPUShaderFP64Test8(m_context));
	fp64->addChild(new GPUShaderFP64Test9(m_context));
	addChild(fp64);

	TypeDefinition typeDefinition[] =
	{
		{ "double",  1, 1 },
		{ "dvec2",   1, 2 },
		{ "dvec3",   1, 3 },
		{ "dvec4",   1, 4 },
		{ "dmat2",   2, 2 },
		{ "dmat2x3", 2, 3 },
		{ "dmat2x4", 2, 4 },
		{ "dmat3x2", 3, 2 },
		{ "dmat3",   3, 3 },
		{ "dmat3x4", 3, 4 },
		{ "dmat4x2", 4, 2 },
		{ "dmat4x3", 4, 3 },
		{ "dmat4",   4, 4 }
	};

	struct BuiltinFunctions
	{
		std::string  name;
		FunctionEnum function;
	} builtinFunctions[] = {
		{ "abs",						FUNCTION_ABS },
		{ "ceil",						FUNCTION_CEIL },
		{ "clamp",						FUNCTION_CLAMP },
		{ "clamp_against_scalar",		FUNCTION_CLAMP_AGAINST_SCALAR },
		{ "cross",						FUNCTION_CROSS },
		{ "determinant",				FUNCTION_DETERMINANT },
		{ "distance",					FUNCTION_DISTANCE },
		{ "dot",						FUNCTION_DOT },
		{ "equal",						FUNCTION_EQUAL },
		{ "faceforward",				FUNCTION_FACEFORWARD },
		{ "floor",						FUNCTION_FLOOR },
		{ "fma",						FUNCTION_FMA },
		{ "fract",						FUNCTION_FRACT },
		{ "frexp",						FUNCTION_FREXP },
		{ "greaterthan",				FUNCTION_GREATERTHAN },
		{ "greaterthanequal",			FUNCTION_GREATERTHANEQUAL },
		{ "inverse",					FUNCTION_INVERSE },
		{ "inversesqrt",				FUNCTION_INVERSESQRT },
		{ "ldexp",						FUNCTION_LDEXP },
		{ "lessthan",					FUNCTION_LESSTHAN },
		{ "lessthanequal",				FUNCTION_LESSTHANEQUAL },
		{ "length",						FUNCTION_LENGTH },
		{ "matrixcompmult",				FUNCTION_MATRIXCOMPMULT },
		{ "max",						FUNCTION_MAX },
		{ "max_against_scalar",			FUNCTION_MAX_AGAINST_SCALAR },
		{ "min",						FUNCTION_MIN },
		{ "min_against_scalar",			FUNCTION_MIN_AGAINST_SCALAR },
		{ "mix",						FUNCTION_MIX },
		{ "mod",						FUNCTION_MOD },
		{ "mod_against_scalar",			FUNCTION_MOD_AGAINST_SCALAR },
		{ "modf",						FUNCTION_MODF },
		{ "normalize",					FUNCTION_NORMALIZE },
		{ "notequal",					FUNCTION_NOTEQUAL },
		{ "outerproduct",				FUNCTION_OUTERPRODUCT },
		{ "packdouble2x32",				FUNCTION_PACKDOUBLE2X32 },
		{ "reflect",					FUNCTION_REFLECT },
		{ "refract",					FUNCTION_REFRACT },
		{ "round",						FUNCTION_ROUND },
		{ "roundeven",					FUNCTION_ROUNDEVEN },
		{ "sign",						FUNCTION_SIGN },
		{ "smoothstep",					FUNCTION_SMOOTHSTEP },
		{ "smoothstep_against_scalar",	FUNCTION_SMOOTHSTEP_AGAINST_SCALAR },
		{ "sqrt",						FUNCTION_SQRT },
		{ "step",						FUNCTION_STEP },
		{ "step_against_scalar",		FUNCTION_STEP_AGAINST_SCALAR },
		{ "transpose",					FUNCTION_TRANSPOSE },
		{ "trunc",						FUNCTION_TRUNC },
		{ "unpackdouble2x32",			FUNCTION_UNPACKDOUBLE2X32 },
		{ "isnan",						FUNCTION_ISNAN },
		{ "isinf",						FUNCTION_ISINF }
	};

	TestCaseGroup* builin = new TestCaseGroup(m_context, "builtin", "");
	for (int i = 0; i < DE_LENGTH_OF_ARRAY(builtinFunctions); ++i)
	{
		const BuiltinFunctions& bf = builtinFunctions[i];
		for (int j = 0; j < DE_LENGTH_OF_ARRAY(typeDefinition); ++j)
		{
			std::string caseName = bf.name + "_" + typeDefinition[j].name;
			builin->addChild(new BuiltinFunctionTest(m_context, caseName, bf.function, typeDefinition[j]));
		}
	}
	addChild(builin);
}

} /* glcts namespace */
