Home | History | Annotate | Download | only in gl
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2014-2016 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  */ /*!
     20  * \file
     21  * \brief
     22  */ /*-------------------------------------------------------------------*/
     23 
     24 /**
     25  * \file  gl4GPUShaderFP64Tests.cpp
     26  * \brief Implements conformance tests for "GPU Shader FP64" functionality.
     27  */ /*-------------------------------------------------------------------*/
     28 
     29 #include "gl4cGPUShaderFP64Tests.hpp"
     30 #include "gluContextInfo.hpp"
     31 #include "glwFunctions.hpp"
     32 #include "tcuMatrix.hpp"
     33 #include "tcuTestLog.hpp"
     34 
     35 #include <iomanip>
     36 
     37 #include "deMath.h"
     38 #include "deUniquePtr.hpp"
     39 #include "tcuMatrixUtil.hpp"
     40 #include "tcuVectorUtil.hpp"
     41 
     42 #include <cstdlib>
     43 #include <cstring>
     44 #include <limits>
     45 #include <memory>
     46 
     47 namespace gl4cts
     48 {
     49 
     50 const glw::GLenum Utils::programInfo::ARB_COMPUTE_SHADER = 0x91B9;
     51 
     52 /** Constructor
     53  *
     54  * @param context Test context
     55  **/
     56 Utils::programInfo::programInfo(deqp::Context& context)
     57 	: m_context(context)
     58 	, m_compute_shader_id(0)
     59 	, m_fragment_shader_id(0)
     60 	, m_geometry_shader_id(0)
     61 	, m_program_object_id(0)
     62 	, m_tesselation_control_shader_id(0)
     63 	, m_tesselation_evaluation_shader_id(0)
     64 	, m_vertex_shader_id(0)
     65 {
     66 	/* Nothing to be done here */
     67 }
     68 
     69 /** Destructor
     70  *
     71  **/
     72 Utils::programInfo::~programInfo()
     73 {
     74 	/* GL entry points */
     75 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     76 
     77 	/* Make sure program object is no longer used by GL */
     78 	gl.useProgram(0);
     79 
     80 	/* Clean program object */
     81 	if (0 != m_program_object_id)
     82 	{
     83 		gl.deleteProgram(m_program_object_id);
     84 		m_program_object_id = 0;
     85 	}
     86 
     87 	/* Clean shaders */
     88 	if (0 != m_compute_shader_id)
     89 	{
     90 		gl.deleteShader(m_compute_shader_id);
     91 		m_compute_shader_id = 0;
     92 	}
     93 
     94 	if (0 != m_fragment_shader_id)
     95 	{
     96 		gl.deleteShader(m_fragment_shader_id);
     97 		m_fragment_shader_id = 0;
     98 	}
     99 
    100 	if (0 != m_geometry_shader_id)
    101 	{
    102 		gl.deleteShader(m_geometry_shader_id);
    103 		m_geometry_shader_id = 0;
    104 	}
    105 
    106 	if (0 != m_tesselation_control_shader_id)
    107 	{
    108 		gl.deleteShader(m_tesselation_control_shader_id);
    109 		m_tesselation_control_shader_id = 0;
    110 	}
    111 
    112 	if (0 != m_tesselation_evaluation_shader_id)
    113 	{
    114 		gl.deleteShader(m_tesselation_evaluation_shader_id);
    115 		m_tesselation_evaluation_shader_id = 0;
    116 	}
    117 
    118 	if (0 != m_vertex_shader_id)
    119 	{
    120 		gl.deleteShader(m_vertex_shader_id);
    121 		m_vertex_shader_id = 0;
    122 	}
    123 }
    124 
    125 /** Build program
    126  *
    127  * @param compute_shader_code                Compute shader source code
    128  * @param fragment_shader_code               Fragment shader source code
    129  * @param geometry_shader_code               Geometry shader source code
    130  * @param tesselation_control_shader_code    Tesselation control shader source code
    131  * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
    132  * @param vertex_shader_code                 Vertex shader source code
    133  * @param varying_names                      Array of strings containing names of varyings to be captured with transfrom feedback
    134  * @param n_varying_names                    Number of varyings to be captured with transfrom feedback
    135  **/
    136 void Utils::programInfo::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
    137 							   const glw::GLchar* geometry_shader_code,
    138 							   const glw::GLchar* tesselation_control_shader_code,
    139 							   const glw::GLchar* tesselation_evaluation_shader_code,
    140 							   const glw::GLchar* vertex_shader_code, const glw::GLchar* const* varying_names,
    141 							   glw::GLuint n_varying_names)
    142 {
    143 	/* GL entry points */
    144 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    145 
    146 	/* Create shader objects and compile */
    147 	if (0 != compute_shader_code)
    148 	{
    149 		m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
    150 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    151 
    152 		compile(m_compute_shader_id, compute_shader_code);
    153 	}
    154 
    155 	if (0 != fragment_shader_code)
    156 	{
    157 		m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
    158 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    159 
    160 		compile(m_fragment_shader_id, fragment_shader_code);
    161 	}
    162 
    163 	if (0 != geometry_shader_code)
    164 	{
    165 		m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
    166 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    167 
    168 		compile(m_geometry_shader_id, geometry_shader_code);
    169 	}
    170 
    171 	if (0 != tesselation_control_shader_code)
    172 	{
    173 		m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
    174 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    175 
    176 		compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
    177 	}
    178 
    179 	if (0 != tesselation_evaluation_shader_code)
    180 	{
    181 		m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
    182 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    183 
    184 		compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
    185 	}
    186 
    187 	if (0 != vertex_shader_code)
    188 	{
    189 		m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
    190 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    191 
    192 		compile(m_vertex_shader_id, vertex_shader_code);
    193 	}
    194 
    195 	/* Create program object */
    196 	m_program_object_id = gl.createProgram();
    197 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
    198 
    199 	/* Set up captyured varyings' names */
    200 	if (0 != n_varying_names)
    201 	{
    202 		gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
    203 		GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
    204 	}
    205 
    206 	/* Link program */
    207 	link();
    208 }
    209 
    210 /** Compile shader
    211  *
    212  * @param shader_id   Shader object id
    213  * @param shader_code Shader source code
    214  **/
    215 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
    216 {
    217 	/* GL entry points */
    218 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    219 
    220 	/* Compilation status */
    221 	glw::GLint status = GL_FALSE;
    222 
    223 	/* Set source code */
    224 	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
    225 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
    226 
    227 	/* Compile */
    228 	gl.compileShader(shader_id);
    229 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
    230 
    231 	/* Get compilation status */
    232 	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
    233 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    234 
    235 	/* Log compilation error */
    236 	if (GL_TRUE != status)
    237 	{
    238 		glw::GLint				 length = 0;
    239 		std::vector<glw::GLchar> message;
    240 
    241 		/* Error log length */
    242 		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
    243 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    244 
    245 		/* Prepare storage */
    246 		message.resize(length);
    247 
    248 		/* Get error log */
    249 		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
    250 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
    251 
    252 		/* Log */
    253 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
    254 											<< &message[0] << "\nShader source\n"
    255 											<< shader_code << tcu::TestLog::EndMessage;
    256 
    257 		TCU_FAIL("Failed to compile shader");
    258 	}
    259 }
    260 
    261 /** Attach shaders and link program
    262  *
    263  **/
    264 void Utils::programInfo::link() const
    265 {
    266 	/* GL entry points */
    267 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    268 
    269 	/* Link status */
    270 	glw::GLint status = GL_FALSE;
    271 
    272 	/* Attach shaders */
    273 	if (0 != m_compute_shader_id)
    274 	{
    275 		gl.attachShader(m_program_object_id, m_compute_shader_id);
    276 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    277 	}
    278 
    279 	if (0 != m_fragment_shader_id)
    280 	{
    281 		gl.attachShader(m_program_object_id, m_fragment_shader_id);
    282 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    283 	}
    284 
    285 	if (0 != m_geometry_shader_id)
    286 	{
    287 		gl.attachShader(m_program_object_id, m_geometry_shader_id);
    288 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    289 	}
    290 
    291 	if (0 != m_tesselation_control_shader_id)
    292 	{
    293 		gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
    294 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    295 	}
    296 
    297 	if (0 != m_tesselation_evaluation_shader_id)
    298 	{
    299 		gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
    300 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    301 	}
    302 
    303 	if (0 != m_vertex_shader_id)
    304 	{
    305 		gl.attachShader(m_program_object_id, m_vertex_shader_id);
    306 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    307 	}
    308 
    309 	/* Link */
    310 	gl.linkProgram(m_program_object_id);
    311 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
    312 
    313 	/* Get link status */
    314 	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
    315 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    316 
    317 	/* Log link error */
    318 	if (GL_TRUE != status)
    319 	{
    320 		glw::GLint				 length = 0;
    321 		std::vector<glw::GLchar> message;
    322 
    323 		/* Get error log length */
    324 		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
    325 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    326 
    327 		message.resize(length);
    328 
    329 		/* Get error log */
    330 		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
    331 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
    332 
    333 		/* Log */
    334 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
    335 											<< &message[0] << tcu::TestLog::EndMessage;
    336 
    337 		TCU_FAIL("Failed to link program");
    338 	}
    339 }
    340 
    341 /** Retrieves base type of user-provided variable type. (eg. VARIABLE_TYPE_DOUBLE for double-precision
    342  *  matrix types.
    343  *
    344  *  @param type Variable type to return base type for.
    345  *
    346  *  @return Requested value or VARAIBLE_TYPE_UNKNOWN if @param type was not recognized.
    347  **/
    348 Utils::_variable_type Utils::getBaseVariableType(_variable_type type)
    349 {
    350 	_variable_type result = VARIABLE_TYPE_UNKNOWN;
    351 
    352 	switch (type)
    353 	{
    354 	case VARIABLE_TYPE_BOOL:
    355 	{
    356 		result = VARIABLE_TYPE_BOOL;
    357 
    358 		break;
    359 	}
    360 
    361 	case VARIABLE_TYPE_DOUBLE:
    362 	case VARIABLE_TYPE_DMAT2:
    363 	case VARIABLE_TYPE_DMAT2X3:
    364 	case VARIABLE_TYPE_DMAT2X4:
    365 	case VARIABLE_TYPE_DMAT3:
    366 	case VARIABLE_TYPE_DMAT3X2:
    367 	case VARIABLE_TYPE_DMAT3X4:
    368 	case VARIABLE_TYPE_DMAT4:
    369 	case VARIABLE_TYPE_DMAT4X2:
    370 	case VARIABLE_TYPE_DMAT4X3:
    371 	case VARIABLE_TYPE_DVEC2:
    372 	case VARIABLE_TYPE_DVEC3:
    373 	case VARIABLE_TYPE_DVEC4:
    374 	{
    375 		result = VARIABLE_TYPE_DOUBLE;
    376 
    377 		break;
    378 	}
    379 
    380 	case VARIABLE_TYPE_INT:
    381 	case VARIABLE_TYPE_IVEC2:
    382 	case VARIABLE_TYPE_IVEC3:
    383 	case VARIABLE_TYPE_IVEC4:
    384 	{
    385 		result = VARIABLE_TYPE_INT;
    386 
    387 		break;
    388 	}
    389 
    390 	case VARIABLE_TYPE_UINT:
    391 	case VARIABLE_TYPE_UVEC2:
    392 	case VARIABLE_TYPE_UVEC3:
    393 	case VARIABLE_TYPE_UVEC4:
    394 	{
    395 		result = VARIABLE_TYPE_UINT;
    396 
    397 		break;
    398 	}
    399 
    400 	case VARIABLE_TYPE_FLOAT:
    401 	case VARIABLE_TYPE_MAT2:
    402 	case VARIABLE_TYPE_MAT2X3:
    403 	case VARIABLE_TYPE_MAT2X4:
    404 	case VARIABLE_TYPE_MAT3:
    405 	case VARIABLE_TYPE_MAT3X2:
    406 	case VARIABLE_TYPE_MAT3X4:
    407 	case VARIABLE_TYPE_MAT4:
    408 	case VARIABLE_TYPE_MAT4X2:
    409 	case VARIABLE_TYPE_MAT4X3:
    410 	case VARIABLE_TYPE_VEC2:
    411 	case VARIABLE_TYPE_VEC3:
    412 	case VARIABLE_TYPE_VEC4:
    413 	{
    414 		result = VARIABLE_TYPE_FLOAT;
    415 
    416 		break;
    417 	}
    418 
    419 	default:
    420 	{
    421 		TCU_FAIL("Unrecognized variable type");
    422 	}
    423 	} /* switch (type) */
    424 
    425 	return result;
    426 }
    427 
    428 /** Returns size (in bytes) of a single component of a base variable type.
    429  *
    430  *  @param type Base variable type to use for the query.
    431  *
    432  *  @return Requested value or 0 if @param type was not recognized.
    433  **/
    434 unsigned int Utils::getBaseVariableTypeComponentSize(_variable_type type)
    435 {
    436 	unsigned int result = 0;
    437 
    438 	switch (type)
    439 	{
    440 	case VARIABLE_TYPE_BOOL:
    441 		result = sizeof(bool);
    442 		break;
    443 	case VARIABLE_TYPE_DOUBLE:
    444 		result = sizeof(double);
    445 		break;
    446 	case VARIABLE_TYPE_FLOAT:
    447 		result = sizeof(float);
    448 		break;
    449 	case VARIABLE_TYPE_INT:
    450 		result = sizeof(int);
    451 		break;
    452 	case VARIABLE_TYPE_UINT:
    453 		result = sizeof(unsigned int);
    454 		break;
    455 
    456 	default:
    457 	{
    458 		TCU_FAIL("Unrecognized variable type");
    459 	}
    460 	} /* switch (type) */
    461 
    462 	return result;
    463 }
    464 
    465 /** Returns component, corresponding to user-specified index
    466  *  (eg. index:0 corresponds to 'x', index:1 corresponds to 'y',
    467  *  and so on.
    468  *
    469  *  @param index Component index.
    470  *
    471  *  @return As per description.
    472  **/
    473 unsigned char Utils::getComponentAtIndex(unsigned int index)
    474 {
    475 	unsigned char result = '?';
    476 
    477 	switch (index)
    478 	{
    479 	case 0:
    480 		result = 'x';
    481 		break;
    482 	case 1:
    483 		result = 'y';
    484 		break;
    485 	case 2:
    486 		result = 'z';
    487 		break;
    488 	case 3:
    489 		result = 'w';
    490 		break;
    491 
    492 	default:
    493 	{
    494 		TCU_FAIL("Unrecognized component index");
    495 	}
    496 	}
    497 
    498 	return result;
    499 }
    500 
    501 /** Get _variable_type representing double-precision type with given dimmensions
    502  *
    503  * @param n_columns Number of columns
    504  * @param n_row     Number of rows
    505  *
    506  * @return Corresponding _variable_type
    507  **/
    508 Utils::_variable_type Utils::getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
    509 {
    510 	Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
    511 
    512 	static const _variable_type types[4][4] = {
    513 		{ VARIABLE_TYPE_DOUBLE, VARIABLE_TYPE_DVEC2, VARIABLE_TYPE_DVEC3, VARIABLE_TYPE_DVEC4 },
    514 		{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT2, VARIABLE_TYPE_DMAT2X3, VARIABLE_TYPE_DMAT2X4 },
    515 		{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT3X2, VARIABLE_TYPE_DMAT3, VARIABLE_TYPE_DMAT3X4 },
    516 		{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT4X2, VARIABLE_TYPE_DMAT4X3, VARIABLE_TYPE_DMAT4 }
    517 	};
    518 
    519 	type = types[n_columns - 1][n_rows - 1];
    520 
    521 	return type;
    522 }
    523 
    524 /** Returns a single-precision equivalent of a double-precision floating-point variable
    525  *  type.
    526  *
    527  *  @param type Double-precision variable type. Only VARIABLE_TYPE_D* variable types
    528  *              are accepted.
    529  *
    530  *  @return Requested GLSL type.
    531  **/
    532 std::string Utils::getFPVariableTypeStringForVariableType(_variable_type type)
    533 {
    534 	std::string result = "[?]";
    535 
    536 	switch (type)
    537 	{
    538 	case VARIABLE_TYPE_DOUBLE:
    539 		result = "float";
    540 		break;
    541 	case VARIABLE_TYPE_DMAT2:
    542 		result = "mat2";
    543 		break;
    544 	case VARIABLE_TYPE_DMAT2X3:
    545 		result = "mat2x3";
    546 		break;
    547 	case VARIABLE_TYPE_DMAT2X4:
    548 		result = "mat2x4";
    549 		break;
    550 	case VARIABLE_TYPE_DMAT3:
    551 		result = "mat3";
    552 		break;
    553 	case VARIABLE_TYPE_DMAT3X2:
    554 		result = "mat3x2";
    555 		break;
    556 	case VARIABLE_TYPE_DMAT3X4:
    557 		result = "mat3x4";
    558 		break;
    559 	case VARIABLE_TYPE_DMAT4:
    560 		result = "mat4";
    561 		break;
    562 	case VARIABLE_TYPE_DMAT4X2:
    563 		result = "mat4x2";
    564 		break;
    565 	case VARIABLE_TYPE_DMAT4X3:
    566 		result = "mat4x3";
    567 		break;
    568 	case VARIABLE_TYPE_DVEC2:
    569 		result = "vec2";
    570 		break;
    571 	case VARIABLE_TYPE_DVEC3:
    572 		result = "vec3";
    573 		break;
    574 	case VARIABLE_TYPE_DVEC4:
    575 		result = "vec4";
    576 		break;
    577 
    578 	default:
    579 	{
    580 		TCU_FAIL("Unrecognized variable type");
    581 	}
    582 	}; /* switch (type) */
    583 
    584 	return result;
    585 }
    586 
    587 /** Returns GL data type enum corresponding to user-provided base variable type.
    588  *
    589  *  @param type Base variable type to return corresponding GLenum value for.
    590  *
    591  *  @return Corresponding GLenum value or GL_NONE if the input value was not
    592  *          recognized.
    593  **/
    594 glw::GLenum Utils::getGLDataTypeOfBaseVariableType(_variable_type type)
    595 {
    596 	glw::GLenum result = GL_NONE;
    597 
    598 	switch (type)
    599 	{
    600 	case VARIABLE_TYPE_BOOL:
    601 		result = GL_BOOL;
    602 		break;
    603 	case VARIABLE_TYPE_DOUBLE:
    604 		result = GL_DOUBLE;
    605 		break;
    606 	case VARIABLE_TYPE_FLOAT:
    607 		result = GL_FLOAT;
    608 		break;
    609 	case VARIABLE_TYPE_INT:
    610 		result = GL_INT;
    611 		break;
    612 	case VARIABLE_TYPE_UINT:
    613 		result = GL_UNSIGNED_INT;
    614 		break;
    615 
    616 	default:
    617 	{
    618 		TCU_FAIL("Unrecognized variable type");
    619 	}
    620 	}
    621 
    622 	return result;
    623 }
    624 
    625 /** Return GLenum representing given <type>
    626  *
    627  * @param type Type of variable
    628  *
    629  * @return GL enumeration
    630  **/
    631 glw::GLenum Utils::getGLDataTypeOfVariableType(_variable_type type)
    632 {
    633 	glw::GLenum result = GL_NONE;
    634 
    635 	switch (type)
    636 	{
    637 	case VARIABLE_TYPE_BOOL:
    638 		result = GL_BOOL;
    639 		break;
    640 	case VARIABLE_TYPE_DOUBLE:
    641 		result = GL_DOUBLE;
    642 		break;
    643 	case VARIABLE_TYPE_DMAT2:
    644 		result = GL_DOUBLE_MAT2;
    645 		break;
    646 	case VARIABLE_TYPE_DMAT2X3:
    647 		result = GL_DOUBLE_MAT2x3;
    648 		break;
    649 	case VARIABLE_TYPE_DMAT2X4:
    650 		result = GL_DOUBLE_MAT2x4;
    651 		break;
    652 	case VARIABLE_TYPE_DMAT3:
    653 		result = GL_DOUBLE_MAT3;
    654 		break;
    655 	case VARIABLE_TYPE_DMAT3X2:
    656 		result = GL_DOUBLE_MAT3x2;
    657 		break;
    658 	case VARIABLE_TYPE_DMAT3X4:
    659 		result = GL_DOUBLE_MAT3x4;
    660 		break;
    661 	case VARIABLE_TYPE_DMAT4:
    662 		result = GL_DOUBLE_MAT4;
    663 		break;
    664 	case VARIABLE_TYPE_DMAT4X2:
    665 		result = GL_DOUBLE_MAT4x2;
    666 		break;
    667 	case VARIABLE_TYPE_DMAT4X3:
    668 		result = GL_DOUBLE_MAT4x3;
    669 		break;
    670 	case VARIABLE_TYPE_DVEC2:
    671 		result = GL_DOUBLE_VEC2;
    672 		break;
    673 	case VARIABLE_TYPE_DVEC3:
    674 		result = GL_DOUBLE_VEC3;
    675 		break;
    676 	case VARIABLE_TYPE_DVEC4:
    677 		result = GL_DOUBLE_VEC4;
    678 		break;
    679 	case VARIABLE_TYPE_FLOAT:
    680 		result = GL_FLOAT;
    681 		break;
    682 	case VARIABLE_TYPE_INT:
    683 		result = GL_INT;
    684 		break;
    685 	case VARIABLE_TYPE_IVEC2:
    686 		result = GL_INT_VEC2;
    687 		break;
    688 	case VARIABLE_TYPE_IVEC3:
    689 		result = GL_INT_VEC3;
    690 		break;
    691 	case VARIABLE_TYPE_IVEC4:
    692 		result = GL_INT_VEC4;
    693 		break;
    694 	case VARIABLE_TYPE_MAT2:
    695 		result = GL_FLOAT_MAT2;
    696 		break;
    697 	case VARIABLE_TYPE_MAT2X3:
    698 		result = GL_FLOAT_MAT2x3;
    699 		break;
    700 	case VARIABLE_TYPE_MAT2X4:
    701 		result = GL_FLOAT_MAT2x4;
    702 		break;
    703 	case VARIABLE_TYPE_MAT3:
    704 		result = GL_FLOAT_MAT3;
    705 		break;
    706 	case VARIABLE_TYPE_MAT3X2:
    707 		result = GL_FLOAT_MAT3x2;
    708 		break;
    709 	case VARIABLE_TYPE_MAT3X4:
    710 		result = GL_FLOAT_MAT3x4;
    711 		break;
    712 	case VARIABLE_TYPE_MAT4:
    713 		result = GL_FLOAT_MAT4;
    714 		break;
    715 	case VARIABLE_TYPE_MAT4X2:
    716 		result = GL_FLOAT_MAT4x2;
    717 		break;
    718 	case VARIABLE_TYPE_MAT4X3:
    719 		result = GL_FLOAT_MAT4x3;
    720 		break;
    721 	case VARIABLE_TYPE_UINT:
    722 		result = GL_UNSIGNED_INT;
    723 		break;
    724 	case VARIABLE_TYPE_UVEC2:
    725 		result = GL_UNSIGNED_INT_VEC2;
    726 		break;
    727 	case VARIABLE_TYPE_UVEC3:
    728 		result = GL_UNSIGNED_INT_VEC3;
    729 		break;
    730 	case VARIABLE_TYPE_UVEC4:
    731 		result = GL_UNSIGNED_INT_VEC4;
    732 		break;
    733 	case VARIABLE_TYPE_VEC2:
    734 		result = GL_FLOAT_VEC2;
    735 		break;
    736 	case VARIABLE_TYPE_VEC3:
    737 		result = GL_FLOAT_VEC3;
    738 		break;
    739 	case VARIABLE_TYPE_VEC4:
    740 		result = GL_FLOAT_VEC4;
    741 		break;
    742 
    743 	default:
    744 	{
    745 		TCU_FAIL("Unrecognized variable type");
    746 	}
    747 	}
    748 
    749 	return result;
    750 }
    751 
    752 /** Get _variable_type representing integer type with given dimmensions
    753  *
    754  * @param n_columns Number of columns
    755  * @param n_row     Number of rows
    756  *
    757  * @return Corresponding _variable_type
    758  **/
    759 Utils::_variable_type Utils::getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
    760 {
    761 	Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
    762 
    763 	static const _variable_type types[4] = { VARIABLE_TYPE_INT, VARIABLE_TYPE_IVEC2, VARIABLE_TYPE_IVEC3,
    764 											 VARIABLE_TYPE_IVEC4 };
    765 
    766 	if (1 != n_columns)
    767 	{
    768 		TCU_FAIL("Not implemented");
    769 	}
    770 	else
    771 	{
    772 		type = types[n_rows - 1];
    773 	}
    774 
    775 	return type;
    776 }
    777 
    778 /** Returns te number of components that variables defined with user-specified type
    779  *  support. For matrix types, total amount of values accessible for the type will be
    780  *  returned.
    781  *
    782  *  @param type Variable type to return the described vale for.
    783  *
    784  *  @return As per description or 0 if @param type was not recognized.
    785  */
    786 unsigned int Utils::getNumberOfComponentsForVariableType(_variable_type type)
    787 {
    788 	unsigned int result = 0;
    789 
    790 	switch (type)
    791 	{
    792 	case VARIABLE_TYPE_BOOL:
    793 	case VARIABLE_TYPE_DOUBLE:
    794 	case VARIABLE_TYPE_FLOAT:
    795 	case VARIABLE_TYPE_INT:
    796 	case VARIABLE_TYPE_UINT:
    797 	{
    798 		result = 1;
    799 
    800 		break;
    801 	}
    802 
    803 	case VARIABLE_TYPE_DVEC2:
    804 	case VARIABLE_TYPE_IVEC2:
    805 	case VARIABLE_TYPE_UVEC2:
    806 	case VARIABLE_TYPE_VEC2:
    807 	{
    808 		result = 2;
    809 
    810 		break;
    811 	}
    812 
    813 	case VARIABLE_TYPE_DVEC3:
    814 	case VARIABLE_TYPE_IVEC3:
    815 	case VARIABLE_TYPE_UVEC3:
    816 	case VARIABLE_TYPE_VEC3:
    817 	{
    818 		result = 3;
    819 
    820 		break;
    821 	}
    822 
    823 	case VARIABLE_TYPE_DVEC4:
    824 	case VARIABLE_TYPE_IVEC4:
    825 	case VARIABLE_TYPE_UVEC4:
    826 	case VARIABLE_TYPE_VEC4:
    827 	{
    828 		result = 4;
    829 
    830 		break;
    831 	}
    832 
    833 	case VARIABLE_TYPE_DMAT2:
    834 	case VARIABLE_TYPE_MAT2:
    835 	{
    836 		result = 2 * 2;
    837 
    838 		break;
    839 	}
    840 
    841 	case VARIABLE_TYPE_DMAT2X3:
    842 	case VARIABLE_TYPE_DMAT3X2:
    843 	case VARIABLE_TYPE_MAT2X3:
    844 	case VARIABLE_TYPE_MAT3X2:
    845 	{
    846 		result = 2 * 3;
    847 
    848 		break;
    849 	}
    850 
    851 	case VARIABLE_TYPE_DMAT2X4:
    852 	case VARIABLE_TYPE_DMAT4X2:
    853 	case VARIABLE_TYPE_MAT2X4:
    854 	case VARIABLE_TYPE_MAT4X2:
    855 	{
    856 		result = 2 * 4;
    857 
    858 		break;
    859 	}
    860 
    861 	case VARIABLE_TYPE_DMAT3:
    862 	case VARIABLE_TYPE_MAT3:
    863 	{
    864 		result = 3 * 3;
    865 
    866 		break;
    867 	}
    868 
    869 	case VARIABLE_TYPE_DMAT3X4:
    870 	case VARIABLE_TYPE_DMAT4X3:
    871 	case VARIABLE_TYPE_MAT3X4:
    872 	case VARIABLE_TYPE_MAT4X3:
    873 	{
    874 		result = 3 * 4;
    875 
    876 		break;
    877 	}
    878 
    879 	case VARIABLE_TYPE_DMAT4:
    880 	case VARIABLE_TYPE_MAT4:
    881 	{
    882 		result = 4 * 4;
    883 
    884 		break;
    885 	}
    886 
    887 	default:
    888 	{
    889 		TCU_FAIL("Unrecognized type");
    890 	}
    891 	} /* switch (type) */
    892 
    893 	return result;
    894 }
    895 
    896 /** Returns number of columns user-specified matrix variable type describes.
    897  *
    898  *  @param type Variable type to use for the query. Only VARIABLE_TYPE_DMAT*
    899  *              values are valid.
    900  *
    901  *  @return As per description.
    902  **/
    903 unsigned int Utils::getNumberOfColumnsForVariableType(_variable_type type)
    904 {
    905 	unsigned int result = 0;
    906 
    907 	switch (type)
    908 	{
    909 	case VARIABLE_TYPE_BOOL:
    910 	case VARIABLE_TYPE_DOUBLE:
    911 	case VARIABLE_TYPE_FLOAT:
    912 	case VARIABLE_TYPE_INT:
    913 	case VARIABLE_TYPE_UINT:
    914 	case VARIABLE_TYPE_DVEC2:
    915 	case VARIABLE_TYPE_IVEC2:
    916 	case VARIABLE_TYPE_UVEC2:
    917 	case VARIABLE_TYPE_VEC2:
    918 	case VARIABLE_TYPE_DVEC3:
    919 	case VARIABLE_TYPE_IVEC3:
    920 	case VARIABLE_TYPE_UVEC3:
    921 	case VARIABLE_TYPE_VEC3:
    922 	case VARIABLE_TYPE_DVEC4:
    923 	case VARIABLE_TYPE_IVEC4:
    924 	case VARIABLE_TYPE_UVEC4:
    925 	case VARIABLE_TYPE_VEC4:
    926 	{
    927 		result = 1;
    928 
    929 		break;
    930 	}
    931 
    932 	case VARIABLE_TYPE_DMAT2:
    933 	case VARIABLE_TYPE_DMAT2X3:
    934 	case VARIABLE_TYPE_DMAT2X4:
    935 	case VARIABLE_TYPE_MAT2:
    936 	case VARIABLE_TYPE_MAT2X3:
    937 	case VARIABLE_TYPE_MAT2X4:
    938 	{
    939 		result = 2;
    940 
    941 		break;
    942 	}
    943 
    944 	case VARIABLE_TYPE_DMAT3:
    945 	case VARIABLE_TYPE_DMAT3X2:
    946 	case VARIABLE_TYPE_DMAT3X4:
    947 	case VARIABLE_TYPE_MAT3:
    948 	case VARIABLE_TYPE_MAT3X2:
    949 	case VARIABLE_TYPE_MAT3X4:
    950 	{
    951 		result = 3;
    952 
    953 		break;
    954 	}
    955 
    956 	case VARIABLE_TYPE_DMAT4:
    957 	case VARIABLE_TYPE_DMAT4X2:
    958 	case VARIABLE_TYPE_DMAT4X3:
    959 	case VARIABLE_TYPE_MAT4:
    960 	case VARIABLE_TYPE_MAT4X2:
    961 	case VARIABLE_TYPE_MAT4X3:
    962 	{
    963 		result = 4;
    964 
    965 		break;
    966 	}
    967 
    968 	default:
    969 	{
    970 		TCU_FAIL("Unrecognized type");
    971 	}
    972 	} /* switch (type) */
    973 
    974 	return result;
    975 }
    976 
    977 /** Returns maximum number of uniform locations taken by user-specified double-precision
    978  *  variable type.
    979  *
    980  *  @param type Variable type to use for the query. Only VARIABLE_TYPE_D* values are valid.
    981  *
    982  *  @return As per description.
    983  **/
    984 unsigned int Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type)
    985 {
    986 	unsigned int result = 0;
    987 
    988 	switch (type)
    989 	{
    990 	case VARIABLE_TYPE_DOUBLE:
    991 		result = 1;
    992 		break;
    993 	case VARIABLE_TYPE_DVEC2:
    994 		result = 1;
    995 		break;
    996 	case VARIABLE_TYPE_DVEC3:
    997 		result = 2;
    998 		break;
    999 	case VARIABLE_TYPE_DVEC4:
   1000 		result = 2;
   1001 		break;
   1002 	case VARIABLE_TYPE_DMAT2:
   1003 		result = 2;
   1004 		break;
   1005 	case VARIABLE_TYPE_DMAT2X3:
   1006 		result = 6;
   1007 		break;
   1008 	case VARIABLE_TYPE_DMAT2X4:
   1009 		result = 8;
   1010 		break;
   1011 	case VARIABLE_TYPE_DMAT3:
   1012 		result = 6;
   1013 		break;
   1014 	case VARIABLE_TYPE_DMAT3X2:
   1015 		result = 4;
   1016 		break;
   1017 	case VARIABLE_TYPE_DMAT3X4:
   1018 		result = 8;
   1019 		break;
   1020 	case VARIABLE_TYPE_DMAT4:
   1021 		result = 8;
   1022 		break;
   1023 	case VARIABLE_TYPE_DMAT4X2:
   1024 		result = 4;
   1025 		break;
   1026 	case VARIABLE_TYPE_DMAT4X3:
   1027 		result = 6;
   1028 		break;
   1029 
   1030 	default:
   1031 	{
   1032 		TCU_FAIL("Unrecognized type");
   1033 	}
   1034 	} /* switch (type) */
   1035 
   1036 	return result;
   1037 }
   1038 
   1039 /** Get number of rows for given variable type
   1040  *
   1041  * @param type Type of variable
   1042  *
   1043  * @return Number of rows
   1044  **/
   1045 unsigned int Utils::getNumberOfRowsForVariableType(_variable_type type)
   1046 {
   1047 	unsigned int result = 0;
   1048 
   1049 	switch (type)
   1050 	{
   1051 	case VARIABLE_TYPE_BOOL:
   1052 	case VARIABLE_TYPE_DOUBLE:
   1053 	case VARIABLE_TYPE_FLOAT:
   1054 	case VARIABLE_TYPE_INT:
   1055 	case VARIABLE_TYPE_UINT:
   1056 	{
   1057 		result = 1;
   1058 
   1059 		break;
   1060 	}
   1061 
   1062 	case VARIABLE_TYPE_DVEC2:
   1063 	case VARIABLE_TYPE_IVEC2:
   1064 	case VARIABLE_TYPE_UVEC2:
   1065 	case VARIABLE_TYPE_VEC2:
   1066 	case VARIABLE_TYPE_DMAT2:
   1067 	case VARIABLE_TYPE_DMAT3X2:
   1068 	case VARIABLE_TYPE_DMAT4X2:
   1069 	case VARIABLE_TYPE_MAT2:
   1070 	case VARIABLE_TYPE_MAT3X2:
   1071 	case VARIABLE_TYPE_MAT4X2:
   1072 	{
   1073 		result = 2;
   1074 
   1075 		break;
   1076 	}
   1077 
   1078 	case VARIABLE_TYPE_DVEC3:
   1079 	case VARIABLE_TYPE_IVEC3:
   1080 	case VARIABLE_TYPE_UVEC3:
   1081 	case VARIABLE_TYPE_VEC3:
   1082 	case VARIABLE_TYPE_DMAT2X3:
   1083 	case VARIABLE_TYPE_DMAT3:
   1084 	case VARIABLE_TYPE_DMAT4X3:
   1085 	case VARIABLE_TYPE_MAT2X3:
   1086 	case VARIABLE_TYPE_MAT3:
   1087 	case VARIABLE_TYPE_MAT4X3:
   1088 	{
   1089 		result = 3;
   1090 
   1091 		break;
   1092 	}
   1093 
   1094 	case VARIABLE_TYPE_DVEC4:
   1095 	case VARIABLE_TYPE_IVEC4:
   1096 	case VARIABLE_TYPE_UVEC4:
   1097 	case VARIABLE_TYPE_VEC4:
   1098 	case VARIABLE_TYPE_DMAT2X4:
   1099 	case VARIABLE_TYPE_DMAT3X4:
   1100 	case VARIABLE_TYPE_DMAT4:
   1101 	case VARIABLE_TYPE_MAT2X4:
   1102 	case VARIABLE_TYPE_MAT3X4:
   1103 	case VARIABLE_TYPE_MAT4:
   1104 	{
   1105 		result = 4;
   1106 
   1107 		break;
   1108 	}
   1109 
   1110 	default:
   1111 	{
   1112 		TCU_FAIL("Unrecognized type");
   1113 	}
   1114 	} /* switch (type) */
   1115 
   1116 	return result;
   1117 }
   1118 
   1119 /** Returns variable type of a matrix constructed by multiplying two matrices.
   1120  *
   1121  *  @param type_matrix_a L-side matrix type.
   1122  *  @param type_matrix_b R-side matrix type.
   1123  *
   1124  *  @return As per description.
   1125  **/
   1126 Utils::_variable_type Utils::getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a,
   1127 																	 _variable_type type_matrix_b)
   1128 {
   1129 	const unsigned int	n_a_columns	  = Utils::getNumberOfColumnsForVariableType(type_matrix_a);
   1130 	const unsigned int	n_a_components   = Utils::getNumberOfComponentsForVariableType(type_matrix_a);
   1131 	const unsigned int	n_a_rows		   = n_a_components / n_a_columns;
   1132 	const unsigned int	n_b_columns	  = Utils::getNumberOfColumnsForVariableType(type_matrix_b);
   1133 	const unsigned int	n_result_columns = n_b_columns;
   1134 	const unsigned int	n_result_rows	= n_a_rows;
   1135 	Utils::_variable_type result;
   1136 
   1137 	switch (n_result_columns)
   1138 	{
   1139 	case 2:
   1140 	{
   1141 		switch (n_result_rows)
   1142 		{
   1143 		case 2:
   1144 			result = VARIABLE_TYPE_DMAT2;
   1145 			break;
   1146 		case 3:
   1147 			result = VARIABLE_TYPE_DMAT2X3;
   1148 			break;
   1149 		case 4:
   1150 			result = VARIABLE_TYPE_DMAT2X4;
   1151 			break;
   1152 
   1153 		default:
   1154 		{
   1155 			TCU_FAIL("Unrecognized amount of rows in result variable");
   1156 		}
   1157 		} /* switch (n_result_rows) */
   1158 
   1159 		break;
   1160 	} /* case 2: */
   1161 
   1162 	case 3:
   1163 	{
   1164 		switch (n_result_rows)
   1165 		{
   1166 		case 2:
   1167 			result = VARIABLE_TYPE_DMAT3X2;
   1168 			break;
   1169 		case 3:
   1170 			result = VARIABLE_TYPE_DMAT3;
   1171 			break;
   1172 		case 4:
   1173 			result = VARIABLE_TYPE_DMAT3X4;
   1174 			break;
   1175 
   1176 		default:
   1177 		{
   1178 			TCU_FAIL("Unrecognized amount of rows in result variable");
   1179 		}
   1180 		} /* switch (n_result_rows) */
   1181 
   1182 		break;
   1183 	} /* case 3: */
   1184 
   1185 	case 4:
   1186 	{
   1187 		switch (n_result_rows)
   1188 		{
   1189 		case 2:
   1190 			result = VARIABLE_TYPE_DMAT4X2;
   1191 			break;
   1192 		case 3:
   1193 			result = VARIABLE_TYPE_DMAT4X3;
   1194 			break;
   1195 		case 4:
   1196 			result = VARIABLE_TYPE_DMAT4;
   1197 			break;
   1198 
   1199 		default:
   1200 		{
   1201 			TCU_FAIL("Unrecognized amount of rows in result variable");
   1202 		}
   1203 		} /* switch (n_result_rows) */
   1204 
   1205 		break;
   1206 	} /* case 4: */
   1207 
   1208 	default:
   1209 	{
   1210 		TCU_FAIL("Unrecognized amount of columns in result variable");
   1211 	}
   1212 	} /* switch (n_result_columns) */
   1213 
   1214 	/* Done */
   1215 	return result;
   1216 }
   1217 
   1218 /** Returns a string holding the value represented by user-provided variable, for which
   1219  *  the data are represented in @param type variable type.
   1220  *
   1221  *  @return As per description.
   1222  **/
   1223 std::string Utils::getStringForVariableTypeValue(_variable_type type, const unsigned char* data_ptr)
   1224 {
   1225 	std::stringstream result_sstream;
   1226 
   1227 	switch (type)
   1228 	{
   1229 	case VARIABLE_TYPE_BOOL:
   1230 		result_sstream << *((bool*)data_ptr);
   1231 		break;
   1232 	case VARIABLE_TYPE_DOUBLE:
   1233 		result_sstream << *((double*)data_ptr);
   1234 		break;
   1235 	case VARIABLE_TYPE_FLOAT:
   1236 		result_sstream << *((float*)data_ptr);
   1237 		break;
   1238 	case VARIABLE_TYPE_INT:
   1239 		result_sstream << *((int*)data_ptr);
   1240 		break;
   1241 	case VARIABLE_TYPE_UINT:
   1242 		result_sstream << *((unsigned int*)data_ptr);
   1243 		break;
   1244 
   1245 	default:
   1246 	{
   1247 		TCU_FAIL("Unrecognized variable type requested");
   1248 	}
   1249 	} /* switch (type) */
   1250 
   1251 	return result_sstream.str();
   1252 }
   1253 
   1254 /** Returns variable type of a transposed matrix of user-specified variable type.
   1255  *
   1256  *  @param type Variable type of the matrix to be transposed.
   1257  *
   1258  *  @return Transposed matrix variable type.
   1259  **/
   1260 Utils::_variable_type Utils::getTransposedMatrixVariableType(Utils::_variable_type type)
   1261 {
   1262 	Utils::_variable_type result;
   1263 
   1264 	switch (type)
   1265 	{
   1266 	case VARIABLE_TYPE_DMAT2:
   1267 		result = VARIABLE_TYPE_DMAT2;
   1268 		break;
   1269 	case VARIABLE_TYPE_DMAT2X3:
   1270 		result = VARIABLE_TYPE_DMAT3X2;
   1271 		break;
   1272 	case VARIABLE_TYPE_DMAT2X4:
   1273 		result = VARIABLE_TYPE_DMAT4X2;
   1274 		break;
   1275 	case VARIABLE_TYPE_DMAT3:
   1276 		result = VARIABLE_TYPE_DMAT3;
   1277 		break;
   1278 	case VARIABLE_TYPE_DMAT3X2:
   1279 		result = VARIABLE_TYPE_DMAT2X3;
   1280 		break;
   1281 	case VARIABLE_TYPE_DMAT3X4:
   1282 		result = VARIABLE_TYPE_DMAT4X3;
   1283 		break;
   1284 	case VARIABLE_TYPE_DMAT4:
   1285 		result = VARIABLE_TYPE_DMAT4;
   1286 		break;
   1287 	case VARIABLE_TYPE_DMAT4X2:
   1288 		result = VARIABLE_TYPE_DMAT2X4;
   1289 		break;
   1290 	case VARIABLE_TYPE_DMAT4X3:
   1291 		result = VARIABLE_TYPE_DMAT3X4;
   1292 		break;
   1293 
   1294 	default:
   1295 	{
   1296 		TCU_FAIL("Unrecognized double-precision matrix variable type.");
   1297 	}
   1298 	} /* switch (type) */
   1299 
   1300 	return result;
   1301 }
   1302 
   1303 /** Get _variable_type representing unsigned integer type with given dimmensions
   1304  *
   1305  * @param n_columns Number of columns
   1306  * @param n_row     Number of rows
   1307  *
   1308  * @return Corresponding _variable_type
   1309  **/
   1310 Utils::_variable_type Utils::getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
   1311 {
   1312 	Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
   1313 
   1314 	static const _variable_type types[4] = { VARIABLE_TYPE_UINT, VARIABLE_TYPE_UVEC2, VARIABLE_TYPE_UVEC3,
   1315 											 VARIABLE_TYPE_UVEC4 };
   1316 
   1317 	if (1 != n_columns)
   1318 	{
   1319 		TCU_FAIL("Not implemented");
   1320 	}
   1321 	else
   1322 	{
   1323 		type = types[n_rows - 1];
   1324 	}
   1325 
   1326 	return type;
   1327 }
   1328 
   1329 /** Returns a literal corresponding to a GLSL keyword describing user-specified
   1330  *  variable type.
   1331  *
   1332  *  @param type Variable type to use for the query.
   1333  *
   1334  *  @return Requested GLSL keyword or [?] if @param type was not recognized.
   1335  **/
   1336 std::string Utils::getVariableTypeString(_variable_type type)
   1337 {
   1338 	std::string result = "[?]";
   1339 
   1340 	switch (type)
   1341 	{
   1342 	case VARIABLE_TYPE_BOOL:
   1343 		result = "bool";
   1344 		break;
   1345 	case VARIABLE_TYPE_BVEC2:
   1346 		result = "bvec2";
   1347 		break;
   1348 	case VARIABLE_TYPE_BVEC3:
   1349 		result = "bvec3";
   1350 		break;
   1351 	case VARIABLE_TYPE_BVEC4:
   1352 		result = "bvec4";
   1353 		break;
   1354 	case VARIABLE_TYPE_DOUBLE:
   1355 		result = "double";
   1356 		break;
   1357 	case VARIABLE_TYPE_DMAT2:
   1358 		result = "dmat2";
   1359 		break;
   1360 	case VARIABLE_TYPE_DMAT2X3:
   1361 		result = "dmat2x3";
   1362 		break;
   1363 	case VARIABLE_TYPE_DMAT2X4:
   1364 		result = "dmat2x4";
   1365 		break;
   1366 	case VARIABLE_TYPE_DMAT3:
   1367 		result = "dmat3";
   1368 		break;
   1369 	case VARIABLE_TYPE_DMAT3X2:
   1370 		result = "dmat3x2";
   1371 		break;
   1372 	case VARIABLE_TYPE_DMAT3X4:
   1373 		result = "dmat3x4";
   1374 		break;
   1375 	case VARIABLE_TYPE_DMAT4:
   1376 		result = "dmat4";
   1377 		break;
   1378 	case VARIABLE_TYPE_DMAT4X2:
   1379 		result = "dmat4x2";
   1380 		break;
   1381 	case VARIABLE_TYPE_DMAT4X3:
   1382 		result = "dmat4x3";
   1383 		break;
   1384 	case VARIABLE_TYPE_DVEC2:
   1385 		result = "dvec2";
   1386 		break;
   1387 	case VARIABLE_TYPE_DVEC3:
   1388 		result = "dvec3";
   1389 		break;
   1390 	case VARIABLE_TYPE_DVEC4:
   1391 		result = "dvec4";
   1392 		break;
   1393 	case VARIABLE_TYPE_FLOAT:
   1394 		result = "float";
   1395 		break;
   1396 	case VARIABLE_TYPE_INT:
   1397 		result = "int";
   1398 		break;
   1399 	case VARIABLE_TYPE_IVEC2:
   1400 		result = "ivec2";
   1401 		break;
   1402 	case VARIABLE_TYPE_IVEC3:
   1403 		result = "ivec3";
   1404 		break;
   1405 	case VARIABLE_TYPE_IVEC4:
   1406 		result = "ivec4";
   1407 		break;
   1408 	case VARIABLE_TYPE_MAT2:
   1409 		result = "mat2";
   1410 		break;
   1411 	case VARIABLE_TYPE_MAT2X3:
   1412 		result = "mat2x3";
   1413 		break;
   1414 	case VARIABLE_TYPE_MAT2X4:
   1415 		result = "mat2x4";
   1416 		break;
   1417 	case VARIABLE_TYPE_MAT3:
   1418 		result = "mat3";
   1419 		break;
   1420 	case VARIABLE_TYPE_MAT3X2:
   1421 		result = "mat3x2";
   1422 		break;
   1423 	case VARIABLE_TYPE_MAT3X4:
   1424 		result = "mat3x4";
   1425 		break;
   1426 	case VARIABLE_TYPE_MAT4:
   1427 		result = "mat4";
   1428 		break;
   1429 	case VARIABLE_TYPE_MAT4X2:
   1430 		result = "mat4x2";
   1431 		break;
   1432 	case VARIABLE_TYPE_MAT4X3:
   1433 		result = "mat4x3";
   1434 		break;
   1435 	case VARIABLE_TYPE_UINT:
   1436 		result = "uint";
   1437 		break;
   1438 	case VARIABLE_TYPE_UVEC2:
   1439 		result = "uvec2";
   1440 		break;
   1441 	case VARIABLE_TYPE_UVEC3:
   1442 		result = "uvec3";
   1443 		break;
   1444 	case VARIABLE_TYPE_UVEC4:
   1445 		result = "uvec4";
   1446 		break;
   1447 	case VARIABLE_TYPE_VEC2:
   1448 		result = "vec2";
   1449 		break;
   1450 	case VARIABLE_TYPE_VEC3:
   1451 		result = "vec3";
   1452 		break;
   1453 	case VARIABLE_TYPE_VEC4:
   1454 		result = "vec4";
   1455 		break;
   1456 
   1457 	default:
   1458 	{
   1459 		TCU_FAIL("Unrecognized variable type");
   1460 	}
   1461 	}; /* switch (type) */
   1462 
   1463 	return result;
   1464 }
   1465 
   1466 /** Check if GL context meets version requirements
   1467  *
   1468  * @param gl             Functions
   1469  * @param required_major Minimum required MAJOR_VERSION
   1470  * @param required_minor Minimum required MINOR_VERSION
   1471  *
   1472  * @return true if GL context version is at least as requested, false otherwise
   1473  **/
   1474 bool Utils::isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor)
   1475 {
   1476 	glw::GLint major = 0;
   1477 	glw::GLint minor = 0;
   1478 
   1479 	gl.getIntegerv(GL_MAJOR_VERSION, &major);
   1480 	gl.getIntegerv(GL_MINOR_VERSION, &minor);
   1481 
   1482 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
   1483 
   1484 	if (major > required_major)
   1485 	{
   1486 		/* Major is higher than required one */
   1487 		return true;
   1488 	}
   1489 	else if (major == required_major)
   1490 	{
   1491 		if (minor >= required_minor)
   1492 		{
   1493 			/* Major is equal to required one */
   1494 			/* Minor is higher than or equal to required one */
   1495 			return true;
   1496 		}
   1497 		else
   1498 		{
   1499 			/* Major is equal to required one */
   1500 			/* Minor is lower than required one */
   1501 			return false;
   1502 		}
   1503 	}
   1504 	else
   1505 	{
   1506 		/* Major is lower than required one */
   1507 		return false;
   1508 	}
   1509 }
   1510 
   1511 /** Tells whether user-specified variable type corresponds to a matrix type.
   1512  *
   1513  *  @param type Variable type to use for the query.
   1514  *
   1515  *  @return true if the variable type describes a matrix, false otherwise.
   1516  **/
   1517 bool Utils::isMatrixVariableType(_variable_type type)
   1518 {
   1519 	return (type == VARIABLE_TYPE_MAT2 || type == VARIABLE_TYPE_MAT3 || type == VARIABLE_TYPE_MAT4 ||
   1520 			type == VARIABLE_TYPE_MAT2X3 || type == VARIABLE_TYPE_MAT2X4 || type == VARIABLE_TYPE_MAT3X2 ||
   1521 			type == VARIABLE_TYPE_MAT3X4 || type == VARIABLE_TYPE_MAT4X2 || type == VARIABLE_TYPE_MAT4X3 ||
   1522 			type == VARIABLE_TYPE_DMAT2 || type == VARIABLE_TYPE_DMAT3 || type == VARIABLE_TYPE_DMAT4 ||
   1523 			type == VARIABLE_TYPE_DMAT2X3 || type == VARIABLE_TYPE_DMAT2X4 || type == VARIABLE_TYPE_DMAT3X2 ||
   1524 			type == VARIABLE_TYPE_DMAT3X4 || type == VARIABLE_TYPE_DMAT4X2 || type == VARIABLE_TYPE_DMAT4X3);
   1525 }
   1526 
   1527 /** Tells whether user-specified variable type is scalar.
   1528  *
   1529  *  @return true if @param type is a scalar variable type, false otherwise.
   1530  **/
   1531 bool Utils::isScalarVariableType(_variable_type type)
   1532 {
   1533 	bool result = false;
   1534 
   1535 	switch (type)
   1536 	{
   1537 	case VARIABLE_TYPE_BOOL:
   1538 		result = true;
   1539 		break;
   1540 	case VARIABLE_TYPE_DOUBLE:
   1541 		result = true;
   1542 		break;
   1543 	case VARIABLE_TYPE_FLOAT:
   1544 		result = true;
   1545 		break;
   1546 	case VARIABLE_TYPE_INT:
   1547 		result = true;
   1548 		break;
   1549 	case VARIABLE_TYPE_UINT:
   1550 		result = true;
   1551 		break;
   1552 	default:
   1553 		break;
   1554 	}; /* switch (type) */
   1555 
   1556 	return result;
   1557 }
   1558 
   1559 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
   1560  *
   1561  * @param token           Token string
   1562  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
   1563  * @param text            String that will be used as replacement for <token>
   1564  * @param string          String to work on
   1565  **/
   1566 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
   1567 						 std::string& string)
   1568 {
   1569 	const size_t text_length	= strlen(text);
   1570 	const size_t token_length   = strlen(token);
   1571 	const size_t token_position = string.find(token, search_position);
   1572 
   1573 	string.replace(token_position, token_length, text, text_length);
   1574 
   1575 	search_position = token_position + text_length;
   1576 }
   1577 
   1578 /** Constructor.
   1579  *
   1580  *  @param context Rendering context.
   1581  *
   1582  **/
   1583 GPUShaderFP64Test1::GPUShaderFP64Test1(deqp::Context& context)
   1584 	: TestCase(context, "errors", "Verifies that various erroneous conditions related to double-precision "
   1585 								  "float uniform support & glUniform*() / glUniformMatrix*() API "
   1586 								  " are reported correctly.")
   1587 	, m_has_test_passed(true)
   1588 	, m_po_bool_arr_uniform_location(0)
   1589 	, m_po_bool_uniform_location(0)
   1590 	, m_po_bvec2_arr_uniform_location(0)
   1591 	, m_po_bvec2_uniform_location(0)
   1592 	, m_po_bvec3_arr_uniform_location(0)
   1593 	, m_po_bvec3_uniform_location(0)
   1594 	, m_po_bvec4_arr_uniform_location(0)
   1595 	, m_po_bvec4_uniform_location(0)
   1596 	, m_po_dmat2_arr_uniform_location(0)
   1597 	, m_po_dmat2_uniform_location(0)
   1598 	, m_po_dmat2x3_arr_uniform_location(0)
   1599 	, m_po_dmat2x3_uniform_location(0)
   1600 	, m_po_dmat2x4_arr_uniform_location(0)
   1601 	, m_po_dmat2x4_uniform_location(0)
   1602 	, m_po_dmat3_arr_uniform_location(0)
   1603 	, m_po_dmat3_uniform_location(0)
   1604 	, m_po_dmat3x2_arr_uniform_location(0)
   1605 	, m_po_dmat3x2_uniform_location(0)
   1606 	, m_po_dmat3x4_arr_uniform_location(0)
   1607 	, m_po_dmat3x4_uniform_location(0)
   1608 	, m_po_dmat4_arr_uniform_location(0)
   1609 	, m_po_dmat4_uniform_location(0)
   1610 	, m_po_dmat4x2_arr_uniform_location(0)
   1611 	, m_po_dmat4x2_uniform_location(0)
   1612 	, m_po_dmat4x3_arr_uniform_location(0)
   1613 	, m_po_dmat4x3_uniform_location(0)
   1614 	, m_po_double_arr_uniform_location(0)
   1615 	, m_po_double_uniform_location(0)
   1616 	, m_po_dvec2_arr_uniform_location(0)
   1617 	, m_po_dvec2_uniform_location(0)
   1618 	, m_po_dvec3_arr_uniform_location(0)
   1619 	, m_po_dvec3_uniform_location(0)
   1620 	, m_po_dvec4_arr_uniform_location(0)
   1621 	, m_po_dvec4_uniform_location(0)
   1622 	, m_po_float_arr_uniform_location(0)
   1623 	, m_po_float_uniform_location(0)
   1624 	, m_po_int_arr_uniform_location(0)
   1625 	, m_po_int_uniform_location(0)
   1626 	, m_po_ivec2_arr_uniform_location(0)
   1627 	, m_po_ivec2_uniform_location(0)
   1628 	, m_po_ivec3_arr_uniform_location(0)
   1629 	, m_po_ivec3_uniform_location(0)
   1630 	, m_po_ivec4_arr_uniform_location(0)
   1631 	, m_po_ivec4_uniform_location(0)
   1632 	, m_po_sampler_uniform_location(0)
   1633 	, m_po_uint_arr_uniform_location(0)
   1634 	, m_po_uint_uniform_location(0)
   1635 	, m_po_uvec2_arr_uniform_location(0)
   1636 	, m_po_uvec2_uniform_location(0)
   1637 	, m_po_uvec3_arr_uniform_location(0)
   1638 	, m_po_uvec3_uniform_location(0)
   1639 	, m_po_uvec4_arr_uniform_location(0)
   1640 	, m_po_uvec4_uniform_location(0)
   1641 	, m_po_vec2_arr_uniform_location(0)
   1642 	, m_po_vec2_uniform_location(0)
   1643 	, m_po_vec3_arr_uniform_location(0)
   1644 	, m_po_vec3_uniform_location(0)
   1645 	, m_po_vec4_arr_uniform_location(0)
   1646 	, m_po_vec4_uniform_location(0)
   1647 	, m_po_id(0)
   1648 	, m_vs_id(0)
   1649 {
   1650 	/* Left blank intentionally */
   1651 }
   1652 
   1653 /** Deinitializes all GL objects that may have been created during
   1654  *  test execution.
   1655  **/
   1656 void GPUShaderFP64Test1::deinit()
   1657 {
   1658 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1659 
   1660 	if (m_po_id != 0)
   1661 	{
   1662 		gl.deleteProgram(m_po_id);
   1663 
   1664 		m_po_id = 0;
   1665 	}
   1666 
   1667 	if (m_vs_id != 0)
   1668 	{
   1669 		gl.deleteShader(m_vs_id);
   1670 
   1671 		m_vs_id = 0;
   1672 	}
   1673 }
   1674 
   1675 /** Returns a string describing GL API function represented by user-provided enum.
   1676  *
   1677  *  @param func Uniform function to return the string for.
   1678  *
   1679  *  @return As per description. [?] will be returned if the function was not recognized.
   1680  **/
   1681 const char* GPUShaderFP64Test1::getUniformFunctionString(_uniform_function func)
   1682 {
   1683 	const char* result = "[?]";
   1684 
   1685 	switch (func)
   1686 	{
   1687 	case UNIFORM_FUNCTION_1D:
   1688 		result = "glUniform1d";
   1689 		break;
   1690 	case UNIFORM_FUNCTION_1DV:
   1691 		result = "glUniform1dv";
   1692 		break;
   1693 	case UNIFORM_FUNCTION_2D:
   1694 		result = "glUniform2d";
   1695 		break;
   1696 	case UNIFORM_FUNCTION_2DV:
   1697 		result = "glUniform2dv";
   1698 		break;
   1699 	case UNIFORM_FUNCTION_3D:
   1700 		result = "glUniform3d";
   1701 		break;
   1702 	case UNIFORM_FUNCTION_3DV:
   1703 		result = "glUniform3dv";
   1704 		break;
   1705 	case UNIFORM_FUNCTION_4D:
   1706 		result = "glUniform4d";
   1707 		break;
   1708 	case UNIFORM_FUNCTION_4DV:
   1709 		result = "glUniform4dv";
   1710 		break;
   1711 	case UNIFORM_FUNCTION_MATRIX2DV:
   1712 		result = "glUniformMatrix2dv";
   1713 		break;
   1714 	case UNIFORM_FUNCTION_MATRIX2X3DV:
   1715 		result = "glUniformMatrix2x3dv";
   1716 		break;
   1717 	case UNIFORM_FUNCTION_MATRIX2X4DV:
   1718 		result = "glUniformMatrix2x4dv";
   1719 		break;
   1720 	case UNIFORM_FUNCTION_MATRIX3DV:
   1721 		result = "glUniformMatrix3dv";
   1722 		break;
   1723 	case UNIFORM_FUNCTION_MATRIX3X2DV:
   1724 		result = "glUniformMatrix3x2dv";
   1725 		break;
   1726 	case UNIFORM_FUNCTION_MATRIX3X4DV:
   1727 		result = "glUniformMatrix3x4dv";
   1728 		break;
   1729 	case UNIFORM_FUNCTION_MATRIX4DV:
   1730 		result = "glUniformMatrix4dv";
   1731 		break;
   1732 	case UNIFORM_FUNCTION_MATRIX4X2DV:
   1733 		result = "glUniformMatrix4x2dv";
   1734 		break;
   1735 	case UNIFORM_FUNCTION_MATRIX4X3DV:
   1736 		result = "glUniformMatrix4x3dv";
   1737 		break;
   1738 	default:
   1739 		break;
   1740 	}
   1741 
   1742 	return result;
   1743 }
   1744 
   1745 /** Returns name of an uniform bound to user-provided location.
   1746  *
   1747  *  @param location Location of the uniform to return the name for.
   1748  *
   1749  *  @return As per description. [?] will be returned if the location was not
   1750  *          recognized.
   1751  **/
   1752 const char* GPUShaderFP64Test1::getUniformNameForLocation(glw::GLint location)
   1753 {
   1754 	const char* result = "[?]";
   1755 
   1756 	if (location == m_po_bool_arr_uniform_location)
   1757 		result = "uniform_bool_arr";
   1758 	else if (location == m_po_bool_uniform_location)
   1759 		result = "uniform_bool";
   1760 	else if (location == m_po_bvec2_arr_uniform_location)
   1761 		result = "uniform_bvec2_arr";
   1762 	else if (location == m_po_bvec2_uniform_location)
   1763 		result = "uniform_bvec2";
   1764 	else if (location == m_po_bvec3_arr_uniform_location)
   1765 		result = "uniform_bvec3_arr";
   1766 	else if (location == m_po_bvec3_uniform_location)
   1767 		result = "uniform_bvec3";
   1768 	else if (location == m_po_bvec4_arr_uniform_location)
   1769 		result = "uniform_bvec4_arr";
   1770 	else if (location == m_po_bvec4_uniform_location)
   1771 		result = "uniform_bvec4";
   1772 	else if (location == m_po_dmat2_arr_uniform_location)
   1773 		result = "uniform_dmat2_arr";
   1774 	else if (location == m_po_dmat2_uniform_location)
   1775 		result = "uniform_dmat2";
   1776 	else if (location == m_po_dmat2x3_arr_uniform_location)
   1777 		result = "uniform_dmat2x3_arr";
   1778 	else if (location == m_po_dmat2x3_uniform_location)
   1779 		result = "uniform_dmat2x3";
   1780 	else if (location == m_po_dmat2x4_arr_uniform_location)
   1781 		result = "uniform_dmat2x4_arr";
   1782 	else if (location == m_po_dmat2x4_uniform_location)
   1783 		result = "uniform_dmat2x4";
   1784 	else if (location == m_po_dmat3_arr_uniform_location)
   1785 		result = "uniform_dmat3_arr";
   1786 	else if (location == m_po_dmat3_uniform_location)
   1787 		result = "uniform_dmat3";
   1788 	else if (location == m_po_dmat3x2_arr_uniform_location)
   1789 		result = "uniform_dmat3x2_arr";
   1790 	else if (location == m_po_dmat3x2_uniform_location)
   1791 		result = "uniform_dmat3x2";
   1792 	else if (location == m_po_dmat3x4_arr_uniform_location)
   1793 		result = "uniform_dmat3x4_arr";
   1794 	else if (location == m_po_dmat3x4_uniform_location)
   1795 		result = "uniform_dmat3x4";
   1796 	else if (location == m_po_dmat4_arr_uniform_location)
   1797 		result = "uniform_dmat4_arr";
   1798 	else if (location == m_po_dmat4_uniform_location)
   1799 		result = "uniform_dmat4";
   1800 	else if (location == m_po_dmat4x2_arr_uniform_location)
   1801 		result = "uniform_dmat4x2_arr";
   1802 	else if (location == m_po_dmat4x2_uniform_location)
   1803 		result = "uniform_dmat4x2";
   1804 	else if (location == m_po_dmat4x3_arr_uniform_location)
   1805 		result = "uniform_dmat4x3_arr";
   1806 	else if (location == m_po_dmat4x3_uniform_location)
   1807 		result = "uniform_dmat4x3";
   1808 	else if (location == m_po_double_arr_uniform_location)
   1809 		result = "uniform_double_arr";
   1810 	else if (location == m_po_double_uniform_location)
   1811 		result = "uniform_double";
   1812 	else if (location == m_po_dvec2_arr_uniform_location)
   1813 		result = "uniform_dvec2_arr";
   1814 	else if (location == m_po_dvec2_uniform_location)
   1815 		result = "uniform_dvec2";
   1816 	else if (location == m_po_dvec3_arr_uniform_location)
   1817 		result = "uniform_dvec3_arr";
   1818 	else if (location == m_po_dvec3_uniform_location)
   1819 		result = "uniform_dvec3";
   1820 	else if (location == m_po_dvec4_arr_uniform_location)
   1821 		result = "uniform_dvec4_arr";
   1822 	else if (location == m_po_dvec4_uniform_location)
   1823 		result = "uniform_dvec4";
   1824 	else if (location == m_po_float_arr_uniform_location)
   1825 		result = "uniform_float_arr";
   1826 	else if (location == m_po_float_uniform_location)
   1827 		result = "uniform_float";
   1828 	else if (location == m_po_int_arr_uniform_location)
   1829 		result = "uniform_int_arr";
   1830 	else if (location == m_po_int_uniform_location)
   1831 		result = "uniform_int";
   1832 	else if (location == m_po_ivec2_arr_uniform_location)
   1833 		result = "uniform_ivec2_arr";
   1834 	else if (location == m_po_ivec2_uniform_location)
   1835 		result = "uniform_ivec2";
   1836 	else if (location == m_po_ivec3_arr_uniform_location)
   1837 		result = "uniform_ivec3_arr";
   1838 	else if (location == m_po_ivec3_uniform_location)
   1839 		result = "uniform_ivec3";
   1840 	else if (location == m_po_ivec4_arr_uniform_location)
   1841 		result = "uniform_ivec4_arr";
   1842 	else if (location == m_po_ivec4_uniform_location)
   1843 		result = "uniform_ivec4";
   1844 	else if (location == m_po_uint_arr_uniform_location)
   1845 		result = "uniform_uint_arr";
   1846 	else if (location == m_po_uint_uniform_location)
   1847 		result = "uniform_uint";
   1848 	else if (location == m_po_uvec2_arr_uniform_location)
   1849 		result = "uniform_uvec2_arr";
   1850 	else if (location == m_po_uvec2_uniform_location)
   1851 		result = "uniform_uvec2";
   1852 	else if (location == m_po_uvec3_arr_uniform_location)
   1853 		result = "uniform_uvec3_arr";
   1854 	else if (location == m_po_uvec3_uniform_location)
   1855 		result = "uniform_uvec3";
   1856 	else if (location == m_po_uvec4_arr_uniform_location)
   1857 		result = "uniform_uvec4_arr";
   1858 	else if (location == m_po_uvec4_uniform_location)
   1859 		result = "uniform_uvec4";
   1860 	else if (location == m_po_vec2_arr_uniform_location)
   1861 		result = "uniform_vec2_arr";
   1862 	else if (location == m_po_vec2_uniform_location)
   1863 		result = "uniform_vec2";
   1864 	else if (location == m_po_vec3_arr_uniform_location)
   1865 		result = "uniform_vec3_arr";
   1866 	else if (location == m_po_vec3_uniform_location)
   1867 		result = "uniform_vec3";
   1868 	else if (location == m_po_vec4_arr_uniform_location)
   1869 		result = "uniform_vec4_arr";
   1870 	else if (location == m_po_vec4_uniform_location)
   1871 		result = "uniform_vec4";
   1872 
   1873 	return result;
   1874 }
   1875 
   1876 /** Initializes all GL objects required to run the test. Also extracts locations of all
   1877  *  uniforms used by the test.
   1878  *
   1879  *  This function can throw a TestError exception if the implementation misbehaves.
   1880  */
   1881 void GPUShaderFP64Test1::initTest()
   1882 {
   1883 	glw::GLint			  compile_status = GL_FALSE;
   1884 	const glw::Functions& gl			 = m_context.getRenderContext().getFunctions();
   1885 	glw::GLint			  link_status	= GL_FALSE;
   1886 
   1887 	/* Set up a program object using all new double-precision types */
   1888 	const char* vs_body =
   1889 		"#version 400\n"
   1890 		"\n"
   1891 		"uniform bool      uniform_bool;\n"
   1892 		"uniform bvec2     uniform_bvec2;\n"
   1893 		"uniform bvec3     uniform_bvec3;\n"
   1894 		"uniform bvec4     uniform_bvec4;\n"
   1895 		"uniform dmat2     uniform_dmat2;\n"
   1896 		"uniform dmat2x3   uniform_dmat2x3;\n"
   1897 		"uniform dmat2x4   uniform_dmat2x4;\n"
   1898 		"uniform dmat3     uniform_dmat3;\n"
   1899 		"uniform dmat3x2   uniform_dmat3x2;\n"
   1900 		"uniform dmat3x4   uniform_dmat3x4;\n"
   1901 		"uniform dmat4     uniform_dmat4;\n"
   1902 		"uniform dmat4x2   uniform_dmat4x2;\n"
   1903 		"uniform dmat4x3   uniform_dmat4x3;\n"
   1904 		"uniform double    uniform_double;\n"
   1905 		"uniform dvec2     uniform_dvec2;\n"
   1906 		"uniform dvec3     uniform_dvec3;\n"
   1907 		"uniform dvec4     uniform_dvec4;\n"
   1908 		"uniform float     uniform_float;\n"
   1909 		"uniform int       uniform_int;\n"
   1910 		"uniform ivec2     uniform_ivec2;\n"
   1911 		"uniform ivec3     uniform_ivec3;\n"
   1912 		"uniform ivec4     uniform_ivec4;\n"
   1913 		"uniform sampler2D uniform_sampler;\n"
   1914 		"uniform uint      uniform_uint;\n"
   1915 		"uniform uvec2     uniform_uvec2;\n"
   1916 		"uniform uvec3     uniform_uvec3;\n"
   1917 		"uniform uvec4     uniform_uvec4;\n"
   1918 		"uniform vec2      uniform_vec2;\n"
   1919 		"uniform vec3      uniform_vec3;\n"
   1920 		"uniform vec4      uniform_vec4;\n"
   1921 		"uniform bool      uniform_bool_arr   [2];\n"
   1922 		"uniform bvec2     uniform_bvec2_arr  [2];\n"
   1923 		"uniform bvec3     uniform_bvec3_arr  [2];\n"
   1924 		"uniform bvec4     uniform_bvec4_arr  [2];\n"
   1925 		"uniform dmat2     uniform_dmat2_arr  [2];\n"
   1926 		"uniform dmat2x3   uniform_dmat2x3_arr[2];\n"
   1927 		"uniform dmat2x4   uniform_dmat2x4_arr[2];\n"
   1928 		"uniform dmat3     uniform_dmat3_arr  [2];\n"
   1929 		"uniform dmat3x2   uniform_dmat3x2_arr[2];\n"
   1930 		"uniform dmat3x4   uniform_dmat3x4_arr[2];\n"
   1931 		"uniform dmat4     uniform_dmat4_arr  [2];\n"
   1932 		"uniform dmat4x2   uniform_dmat4x2_arr[2];\n"
   1933 		"uniform dmat4x3   uniform_dmat4x3_arr[2];\n"
   1934 		"uniform double    uniform_double_arr [2];\n"
   1935 		"uniform dvec2     uniform_dvec2_arr  [2];\n"
   1936 		"uniform dvec3     uniform_dvec3_arr  [2];\n"
   1937 		"uniform dvec4     uniform_dvec4_arr  [2];\n"
   1938 		"uniform float     uniform_float_arr  [2];\n"
   1939 		"uniform int       uniform_int_arr    [2];\n"
   1940 		"uniform ivec2     uniform_ivec2_arr  [2];\n"
   1941 		"uniform ivec3     uniform_ivec3_arr  [2];\n"
   1942 		"uniform ivec4     uniform_ivec4_arr  [2];\n"
   1943 		"uniform uint      uniform_uint_arr   [2];\n"
   1944 		"uniform uvec2     uniform_uvec2_arr  [2];\n"
   1945 		"uniform uvec3     uniform_uvec3_arr  [2];\n"
   1946 		"uniform uvec4     uniform_uvec4_arr  [2];\n"
   1947 		"uniform vec2      uniform_vec2_arr   [2];\n"
   1948 		"uniform vec3      uniform_vec3_arr   [2];\n"
   1949 		"uniform vec4      uniform_vec4_arr   [2];\n"
   1950 		"\n"
   1951 		"void main()\n"
   1952 		"{\n"
   1953 		"    gl_Position = vec4(0) + texture(uniform_sampler, vec2(0) );\n"
   1954 		"\n"
   1955 		"    if (uniform_bool        && uniform_bvec2.y        && uniform_bvec3.z        && uniform_bvec4.w        &&\n"
   1956 		"        uniform_bool_arr[1] && uniform_bvec2_arr[1].y && uniform_bvec3_arr[1].z && uniform_bvec4_arr[1].w)\n"
   1957 		"    {\n"
   1958 		"        double sum = uniform_dmat2       [0].x + uniform_dmat2x3       [0].x + uniform_dmat2x4       [0].x +\n"
   1959 		"                     uniform_dmat3       [0].x + uniform_dmat3x2       [0].x + uniform_dmat3x4       [0].x +\n"
   1960 		"                     uniform_dmat4       [0].x + uniform_dmat4x2       [0].x + uniform_dmat4x3       [0].x +\n"
   1961 		"                     uniform_dmat2_arr[0][0].x + uniform_dmat2x3_arr[0][0].x + uniform_dmat2x4_arr[0][0].x +\n"
   1962 		"                     uniform_dmat3_arr[0][0].x + uniform_dmat3x2_arr[0][0].x + uniform_dmat3x4_arr[0][0].x +\n"
   1963 		"                     uniform_dmat4_arr[0][0].x + uniform_dmat4x2_arr[0][0].x + uniform_dmat4x3_arr[0][0].x +\n"
   1964 		"                     uniform_double            + uniform_double_arr [0]      +\n"
   1965 		"                     uniform_dvec2.x           + uniform_dvec3.x             + uniform_dvec4.x        +\n"
   1966 		"                     uniform_dvec2_arr[0].x    + uniform_dvec3_arr[0].x      + uniform_dvec4_arr[0].x;\n"
   1967 		"        int   sum2 = uniform_int               + uniform_ivec2.x             + uniform_ivec3.x        +\n"
   1968 		"                     uniform_ivec4.x           + uniform_ivec2_arr[0].x      + uniform_ivec3_arr[0].x +\n"
   1969 		"                     uniform_ivec4_arr[0].x    + uniform_int_arr[0];\n"
   1970 		"        uint  sum3 = uniform_uint              + uniform_uvec2.x             + uniform_uvec3.x        +\n"
   1971 		"                     uniform_uvec4.x           + uniform_uint_arr[0]         + uniform_uvec2_arr[0].x +\n"
   1972 		"                     uniform_uvec3_arr[0].x    + uniform_uvec4_arr[0].x;\n"
   1973 		"        float sum4 = uniform_float             + uniform_float_arr[0]  + \n"
   1974 		"                     uniform_vec2.x            + uniform_vec2_arr[0].x + \n"
   1975 		"                     uniform_vec3.x            + uniform_vec3_arr[0].x + \n"
   1976 		"                     uniform_vec4.x            + uniform_vec4_arr[0].x;\n"
   1977 		"\n"
   1978 		"        if (sum * sum4 > intBitsToFloat(sum2) * uintBitsToFloat(sum3) )\n"
   1979 		"        {\n"
   1980 		"            gl_Position = vec4(1);\n"
   1981 		"        }\n"
   1982 		"    }\n"
   1983 		"}\n";
   1984 
   1985 	m_po_id = gl.createProgram();
   1986 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
   1987 
   1988 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   1989 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   1990 
   1991 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
   1992 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   1993 
   1994 	gl.compileShader(m_vs_id);
   1995 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   1996 
   1997 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   1998 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   1999 
   2000 	if (compile_status != GL_TRUE)
   2001 	{
   2002 		TCU_FAIL("Shader compilation failed.");
   2003 	}
   2004 
   2005 	gl.attachShader(m_po_id, m_vs_id);
   2006 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   2007 
   2008 	gl.linkProgram(m_po_id);
   2009 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   2010 
   2011 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   2012 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   2013 
   2014 	if (link_status != GL_TRUE)
   2015 	{
   2016 		TCU_FAIL("Program linking failed.");
   2017 	}
   2018 
   2019 	m_po_bool_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_bool_arr[0]");
   2020 	m_po_bool_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bool");
   2021 	m_po_bvec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_bvec2_arr[0]");
   2022 	m_po_bvec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bvec2");
   2023 	m_po_bvec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_bvec3_arr[0]");
   2024 	m_po_bvec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bvec3");
   2025 	m_po_bvec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_bvec4_arr[0]");
   2026 	m_po_bvec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_bvec4");
   2027 	m_po_dmat2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dmat2_arr[0]");
   2028 	m_po_dmat2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dmat2");
   2029 	m_po_dmat2x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3_arr[0]");
   2030 	m_po_dmat2x3_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat2x3");
   2031 	m_po_dmat2x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4_arr[0]");
   2032 	m_po_dmat2x4_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat2x4");
   2033 	m_po_dmat3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dmat3_arr[0]");
   2034 	m_po_dmat3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dmat3");
   2035 	m_po_dmat3x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2_arr[0]");
   2036 	m_po_dmat3x2_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat3x2");
   2037 	m_po_dmat3x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4_arr[0]");
   2038 	m_po_dmat3x4_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat3x4");
   2039 	m_po_dmat4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dmat4_arr[0]");
   2040 	m_po_dmat4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dmat4");
   2041 	m_po_dmat4x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2_arr[0]");
   2042 	m_po_dmat4x2_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat4x2");
   2043 	m_po_dmat4x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3_arr[0]");
   2044 	m_po_dmat4x3_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_dmat4x3");
   2045 	m_po_double_arr_uniform_location  = gl.getUniformLocation(m_po_id, "uniform_double_arr[0]");
   2046 	m_po_double_uniform_location	  = gl.getUniformLocation(m_po_id, "uniform_double");
   2047 	m_po_dvec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dvec2_arr[0]");
   2048 	m_po_dvec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dvec2");
   2049 	m_po_dvec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dvec3_arr[0]");
   2050 	m_po_dvec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dvec3");
   2051 	m_po_dvec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_dvec4_arr[0]");
   2052 	m_po_dvec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_dvec4");
   2053 	m_po_float_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_float_arr[0]");
   2054 	m_po_float_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_float");
   2055 	m_po_int_arr_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_int_arr[0]");
   2056 	m_po_int_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_int");
   2057 	m_po_ivec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_ivec2_arr[0]");
   2058 	m_po_ivec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_ivec2");
   2059 	m_po_ivec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_ivec3_arr[0]");
   2060 	m_po_ivec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_ivec3");
   2061 	m_po_ivec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_ivec4_arr[0]");
   2062 	m_po_ivec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_ivec4");
   2063 	m_po_sampler_uniform_location	 = gl.getUniformLocation(m_po_id, "uniform_sampler");
   2064 	m_po_uint_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_uint_arr[0]");
   2065 	m_po_uint_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uint");
   2066 	m_po_uvec2_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_uvec2_arr[0]");
   2067 	m_po_uvec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uvec2");
   2068 	m_po_uvec3_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_uvec3_arr[0]");
   2069 	m_po_uvec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uvec3");
   2070 	m_po_uvec4_arr_uniform_location   = gl.getUniformLocation(m_po_id, "uniform_uvec4_arr[0]");
   2071 	m_po_uvec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_uvec4");
   2072 	m_po_vec2_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_vec2_arr[0]");
   2073 	m_po_vec2_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_vec2");
   2074 	m_po_vec3_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_vec3_arr[0]");
   2075 	m_po_vec3_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_vec3");
   2076 	m_po_vec4_arr_uniform_location	= gl.getUniformLocation(m_po_id, "uniform_vec4_arr[0]");
   2077 	m_po_vec4_uniform_location		  = gl.getUniformLocation(m_po_id, "uniform_vec4");
   2078 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");
   2079 
   2080 	if (m_po_bool_arr_uniform_location == -1 || m_po_bool_uniform_location == -1 ||
   2081 		m_po_bvec2_arr_uniform_location == -1 || m_po_bvec2_uniform_location == -1 ||
   2082 		m_po_bvec3_arr_uniform_location == -1 || m_po_bvec3_uniform_location == -1 ||
   2083 		m_po_bvec4_arr_uniform_location == -1 || m_po_bvec4_uniform_location == -1 ||
   2084 		m_po_dmat2_arr_uniform_location == -1 || m_po_dmat2_uniform_location == -1 ||
   2085 		m_po_dmat2x3_arr_uniform_location == -1 || m_po_dmat2x3_uniform_location == -1 ||
   2086 		m_po_dmat2x4_arr_uniform_location == -1 || m_po_dmat2x4_uniform_location == -1 ||
   2087 		m_po_dmat3_arr_uniform_location == -1 || m_po_dmat3_uniform_location == -1 ||
   2088 		m_po_dmat3x2_arr_uniform_location == -1 || m_po_dmat3x2_uniform_location == -1 ||
   2089 		m_po_dmat3x4_arr_uniform_location == -1 || m_po_dmat3x4_uniform_location == -1 ||
   2090 		m_po_dmat4_arr_uniform_location == -1 || m_po_dmat4_uniform_location == -1 ||
   2091 		m_po_dmat4x2_arr_uniform_location == -1 || m_po_dmat4x2_uniform_location == -1 ||
   2092 		m_po_dmat4x3_arr_uniform_location == -1 || m_po_dmat4x3_uniform_location == -1 ||
   2093 		m_po_double_arr_uniform_location == -1 || m_po_double_uniform_location == -1 ||
   2094 		m_po_dvec2_arr_uniform_location == -1 || m_po_dvec2_uniform_location == -1 ||
   2095 		m_po_dvec3_arr_uniform_location == -1 || m_po_dvec3_uniform_location == -1 ||
   2096 		m_po_dvec4_arr_uniform_location == -1 || m_po_dvec4_uniform_location == -1 ||
   2097 		m_po_float_arr_uniform_location == -1 || m_po_float_uniform_location == -1 ||
   2098 		m_po_int_arr_uniform_location == -1 || m_po_int_uniform_location == -1 ||
   2099 		m_po_ivec2_arr_uniform_location == -1 || m_po_ivec2_uniform_location == -1 ||
   2100 		m_po_ivec3_arr_uniform_location == -1 || m_po_ivec3_uniform_location == -1 ||
   2101 		m_po_ivec4_arr_uniform_location == -1 || m_po_ivec4_uniform_location == -1 ||
   2102 		m_po_sampler_uniform_location == -1 || m_po_uint_arr_uniform_location == -1 ||
   2103 		m_po_uint_uniform_location == -1 || m_po_uvec2_arr_uniform_location == -1 ||
   2104 		m_po_uvec2_uniform_location == -1 || m_po_uvec3_arr_uniform_location == -1 ||
   2105 		m_po_uvec3_uniform_location == -1 || m_po_uvec4_arr_uniform_location == -1 ||
   2106 		m_po_uvec4_uniform_location == -1 || m_po_vec2_arr_uniform_location == -1 || m_po_vec2_uniform_location == -1 ||
   2107 		m_po_vec3_arr_uniform_location == -1 || m_po_vec3_uniform_location == -1 ||
   2108 		m_po_vec4_arr_uniform_location == -1 || m_po_vec4_uniform_location == -1)
   2109 	{
   2110 		TCU_FAIL("At last one of the required uniforms is considered inactive.");
   2111 	}
   2112 }
   2113 
   2114 /** Tells wheter uniform at user-specified location represents a double-precision
   2115  *  matrix uniform.
   2116  *
   2117  *  @param uniform_location Location of the uniform to use for the query.
   2118  *
   2119  *  @return Requested information.
   2120  **/
   2121 bool GPUShaderFP64Test1::isMatrixUniform(glw::GLint uniform_location)
   2122 {
   2123 	return (uniform_location == m_po_dmat2_uniform_location || uniform_location == m_po_dmat2x3_uniform_location ||
   2124 			uniform_location == m_po_dmat2x4_uniform_location || uniform_location == m_po_dmat3_uniform_location ||
   2125 			uniform_location == m_po_dmat3x2_uniform_location || uniform_location == m_po_dmat3x4_uniform_location ||
   2126 			uniform_location == m_po_dmat4_uniform_location || uniform_location == m_po_dmat4x2_uniform_location ||
   2127 			uniform_location == m_po_dmat4x3_uniform_location);
   2128 }
   2129 
   2130 /** Tells whether user-specified uniform function corresponds to one of the
   2131  *  functions in glUniformMatrix*() class.
   2132  *
   2133  *  @param func Uniform function enum to use for the query.
   2134  *
   2135  *  @return true if the specified enum represents one of the glUniformMatrix*() functions,
   2136  *          false otherwise.
   2137  **/
   2138 bool GPUShaderFP64Test1::isMatrixUniformFunction(_uniform_function func)
   2139 {
   2140 	return (func == UNIFORM_FUNCTION_MATRIX2DV || func == UNIFORM_FUNCTION_MATRIX2X3DV ||
   2141 			func == UNIFORM_FUNCTION_MATRIX2X4DV || func == UNIFORM_FUNCTION_MATRIX3DV ||
   2142 			func == UNIFORM_FUNCTION_MATRIX3X2DV || func == UNIFORM_FUNCTION_MATRIX3X4DV ||
   2143 			func == UNIFORM_FUNCTION_MATRIX4DV || func == UNIFORM_FUNCTION_MATRIX4X2DV ||
   2144 			func == UNIFORM_FUNCTION_MATRIX4X3DV);
   2145 }
   2146 
   2147 /** Executes test iteration.
   2148  *
   2149  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   2150  */
   2151 tcu::TestNode::IterateResult GPUShaderFP64Test1::iterate()
   2152 {
   2153 	/* Do not execute the test if GL_ARB_texture_view is not supported */
   2154 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
   2155 	{
   2156 		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
   2157 	}
   2158 
   2159 	/* Initialize all ES objects required to run all the checks */
   2160 	initTest();
   2161 
   2162 	/* Make sure GL_INVALID_OPERATION is generated by glUniform*() and
   2163 	 * glUniformMatrix*() functions if there is no current program object.
   2164 	 */
   2165 	m_has_test_passed &= verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO();
   2166 
   2167 	/* Make sure GL_INVALID_OPERATION is generated by glUniform*() if
   2168 	 * the size of the uniform variable declared in the shader does not
   2169 	 * match the size indicated by the command.
   2170 	 */
   2171 	m_has_test_passed &= verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions();
   2172 
   2173 	/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
   2174 	 * glUniformMatrix*() are used to load a uniform variable of type
   2175 	 * bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4,
   2176 	 * unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array
   2177 	 * of these.
   2178 	 */
   2179 	m_has_test_passed &= verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions();
   2180 
   2181 	/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
   2182 	 * glUniformMatrix*() are used to load incompatible double-typed
   2183 	 * uniforms, as presented below:
   2184 	 *
   2185 	 * I.    double-typed uniform configured by glUniform2d();
   2186 	 * II.   double-typed uniform configured by glUniform3d();
   2187 	 * III.  double-typed uniform configured by glUniform4d();
   2188 	 * IV.   double-typed uniform configured by glUniformMatrix*();
   2189 	 * V.    dvec2-typed  uniform configured by glUniform1d();
   2190 	 * VI.   dvec2-typed  uniform configured by glUniform3d();
   2191 	 * VII.  dvec2-typed  uniform configured by glUniform4d();
   2192 	 * VIII. dvec2-typed  uniform configured by glUniformMatrix*();
   2193 	 *
   2194 	 *                          (etc.)
   2195 	 *
   2196 	 */
   2197 	m_has_test_passed &= verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions();
   2198 
   2199 	/* Make sure GL_INVALID_OPERATION is generated if <location> of
   2200 	 * glUniform*() and glUniformMatrix*() is an invalid uniform
   2201 	 * location for the current program object and location is not
   2202 	 * equal to -1.
   2203 	 */
   2204 	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation();
   2205 
   2206 	/* Make sure GL_INVALID_VALUE is generated if <count> of
   2207 	 * glUniform*() (*dv() functions only) and glUniformMatrix*() is
   2208 	 * negative.
   2209 	 */
   2210 	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount();
   2211 
   2212 	/* Make sure GL_INVALID_OPERATION is generated if <count> of
   2213 	 * glUniform*() (*dv() functions only) and glUniformMatrix*() is
   2214 	 * greater than 1 and the indicated uniform variable is not an
   2215 	 * array variable.
   2216 	 */
   2217 	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount();
   2218 
   2219 	/* Make sure GL_INVALID_OPERATION is generated if a sampler is
   2220 	 * loaded by glUniform*() and glUniformMatrix*().
   2221 	 */
   2222 	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers();
   2223 
   2224 	/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
   2225 	 * glUniformMatrix*() is used to load values for uniforms of
   2226 	 * boolean types.
   2227 	 */
   2228 	m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans();
   2229 
   2230 	if (m_has_test_passed)
   2231 	{
   2232 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2233 	}
   2234 	else
   2235 	{
   2236 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2237 	}
   2238 
   2239 	return STOP;
   2240 }
   2241 
   2242 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
   2243  *  glUniformMatrix*dv() functions is used to load a boolean uniform.
   2244  *
   2245  *  @return true if the implementation was found to behave as expected, false otherwise.
   2246  **/
   2247 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans()
   2248 {
   2249 	const double double_data[] = {
   2250 		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
   2251 	};
   2252 	const glw::Functions& gl				  = m_context.getRenderContext().getFunctions();
   2253 	bool				  result			  = true;
   2254 	glw::GLint			  uniform_locations[] = { m_po_bool_arr_uniform_location,  m_po_bool_uniform_location,
   2255 									   m_po_bvec2_arr_uniform_location, m_po_bvec2_uniform_location,
   2256 									   m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location,
   2257 									   m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location };
   2258 	const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]);
   2259 
   2260 	for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
   2261 		 ++n_uniform_function)
   2262 	{
   2263 		const _uniform_function uniform_function = (_uniform_function)n_uniform_function;
   2264 
   2265 		for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
   2266 		{
   2267 			const glw::GLint uniform_location = uniform_locations[n_uniform_location];
   2268 
   2269 			switch (uniform_function)
   2270 			{
   2271 			case UNIFORM_FUNCTION_1D:
   2272 				gl.uniform1d(uniform_location, 0.0);
   2273 				break;
   2274 			case UNIFORM_FUNCTION_2D:
   2275 				gl.uniform2d(uniform_location, 0.0, 1.0);
   2276 				break;
   2277 			case UNIFORM_FUNCTION_3D:
   2278 				gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
   2279 				break;
   2280 			case UNIFORM_FUNCTION_4D:
   2281 				gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
   2282 				break;
   2283 
   2284 			case UNIFORM_FUNCTION_1DV:
   2285 				gl.uniform1dv(uniform_location, 1 /* count */, double_data);
   2286 				break;
   2287 			case UNIFORM_FUNCTION_2DV:
   2288 				gl.uniform2dv(uniform_location, 1 /* count */, double_data);
   2289 				break;
   2290 			case UNIFORM_FUNCTION_3DV:
   2291 				gl.uniform3dv(uniform_location, 1 /* count */, double_data);
   2292 				break;
   2293 			case UNIFORM_FUNCTION_4DV:
   2294 				gl.uniform4dv(uniform_location, 1 /* count */, double_data);
   2295 				break;
   2296 
   2297 			case UNIFORM_FUNCTION_MATRIX2DV:
   2298 				gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2299 				break;
   2300 			case UNIFORM_FUNCTION_MATRIX2X3DV:
   2301 				gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2302 				break;
   2303 			case UNIFORM_FUNCTION_MATRIX2X4DV:
   2304 				gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2305 				break;
   2306 			case UNIFORM_FUNCTION_MATRIX3DV:
   2307 				gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2308 				break;
   2309 			case UNIFORM_FUNCTION_MATRIX3X2DV:
   2310 				gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2311 				break;
   2312 			case UNIFORM_FUNCTION_MATRIX3X4DV:
   2313 				gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2314 				break;
   2315 			case UNIFORM_FUNCTION_MATRIX4DV:
   2316 				gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2317 				break;
   2318 			case UNIFORM_FUNCTION_MATRIX4X2DV:
   2319 				gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2320 				break;
   2321 			case UNIFORM_FUNCTION_MATRIX4X3DV:
   2322 				gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2323 				break;
   2324 
   2325 			default:
   2326 			{
   2327 				TCU_FAIL("Unrecognized uniform function");
   2328 			}
   2329 			}
   2330 
   2331 			/* Make sure GL_INVALID_OPERATION was generated by the call */
   2332 			const glw::GLenum error_code = gl.getError();
   2333 
   2334 			if (error_code != GL_INVALID_OPERATION)
   2335 			{
   2336 				m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
   2337 								   << "() did not generate an error"
   2338 									  " when applied against a boolean uniform."
   2339 								   << tcu::TestLog::EndMessage;
   2340 
   2341 				result = false;
   2342 			}
   2343 		} /* for (all bool uniforms) */
   2344 	}	 /* for (all uniform functions) */
   2345 
   2346 	return result;
   2347 }
   2348 
   2349 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
   2350  *  glUniformMatrix*dv() functions is used to load a sampler2D uniform.
   2351  *
   2352  *  @return true if the implementation was found to behave as expected, false otherwise.
   2353  **/
   2354 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers()
   2355 {
   2356 	const double double_data[] = {
   2357 		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
   2358 	};
   2359 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   2360 	bool				  result = true;
   2361 
   2362 	for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
   2363 		 ++n_uniform_function)
   2364 	{
   2365 		_uniform_function uniform_function = (_uniform_function)n_uniform_function;
   2366 
   2367 		switch (uniform_function)
   2368 		{
   2369 		case UNIFORM_FUNCTION_1D:
   2370 			gl.uniform1d(m_po_sampler_uniform_location, 0.0);
   2371 			break;
   2372 		case UNIFORM_FUNCTION_2D:
   2373 			gl.uniform2d(m_po_sampler_uniform_location, 0.0, 1.0);
   2374 			break;
   2375 		case UNIFORM_FUNCTION_3D:
   2376 			gl.uniform3d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0);
   2377 			break;
   2378 		case UNIFORM_FUNCTION_4D:
   2379 			gl.uniform4d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0, 3.0);
   2380 			break;
   2381 
   2382 		case UNIFORM_FUNCTION_1DV:
   2383 			gl.uniform1dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
   2384 			break;
   2385 		case UNIFORM_FUNCTION_2DV:
   2386 			gl.uniform2dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
   2387 			break;
   2388 		case UNIFORM_FUNCTION_3DV:
   2389 			gl.uniform3dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
   2390 			break;
   2391 		case UNIFORM_FUNCTION_4DV:
   2392 			gl.uniform4dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
   2393 			break;
   2394 
   2395 		case UNIFORM_FUNCTION_MATRIX2DV:
   2396 			gl.uniformMatrix2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2397 			break;
   2398 		case UNIFORM_FUNCTION_MATRIX2X3DV:
   2399 			gl.uniformMatrix2x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2400 			break;
   2401 		case UNIFORM_FUNCTION_MATRIX2X4DV:
   2402 			gl.uniformMatrix2x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2403 			break;
   2404 		case UNIFORM_FUNCTION_MATRIX3DV:
   2405 			gl.uniformMatrix3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2406 			break;
   2407 		case UNIFORM_FUNCTION_MATRIX3X2DV:
   2408 			gl.uniformMatrix3x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2409 			break;
   2410 		case UNIFORM_FUNCTION_MATRIX3X4DV:
   2411 			gl.uniformMatrix3x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2412 			break;
   2413 		case UNIFORM_FUNCTION_MATRIX4DV:
   2414 			gl.uniformMatrix4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2415 			break;
   2416 		case UNIFORM_FUNCTION_MATRIX4X2DV:
   2417 			gl.uniformMatrix4x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2418 			break;
   2419 		case UNIFORM_FUNCTION_MATRIX4X3DV:
   2420 			gl.uniformMatrix4x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2421 			break;
   2422 
   2423 		default:
   2424 		{
   2425 			TCU_FAIL("Unrecognized uniform function");
   2426 		}
   2427 		}
   2428 
   2429 		/* Make sure GL_INVALID_OPERATION was generated by the call */
   2430 		const glw::GLenum error_code = gl.getError();
   2431 
   2432 		if (error_code != GL_INVALID_OPERATION)
   2433 		{
   2434 			m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
   2435 							   << "() did not generate an error"
   2436 								  " when applied against a sampler uniform."
   2437 							   << tcu::TestLog::EndMessage;
   2438 
   2439 			result = false;
   2440 		}
   2441 	} /* for (all uniform functions) */
   2442 
   2443 	return result;
   2444 }
   2445 
   2446 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*dv() or
   2447  *  glUniformMatrix*dv() functions is used to load a compatible uniform using an
   2448  *  invalid <count> argument.
   2449  *
   2450  *  @return true if the implementation was found to behave as expected, false otherwise.
   2451  **/
   2452 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount()
   2453 {
   2454 	const glw::GLdouble double_values[16] = { 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
   2455 											  9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
   2456 	const glw::Functions&   gl					= m_context.getRenderContext().getFunctions();
   2457 	bool					result				= true;
   2458 	const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV,		  UNIFORM_FUNCTION_2DV,
   2459 													UNIFORM_FUNCTION_3DV,		  UNIFORM_FUNCTION_4DV,
   2460 													UNIFORM_FUNCTION_MATRIX2DV,   UNIFORM_FUNCTION_MATRIX2X3DV,
   2461 													UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
   2462 													UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
   2463 													UNIFORM_FUNCTION_MATRIX4DV,   UNIFORM_FUNCTION_MATRIX4X2DV,
   2464 													UNIFORM_FUNCTION_MATRIX4X3DV };
   2465 	const glw::GLint uniforms[] = {
   2466 		m_po_bool_uniform_location,	m_po_bvec2_uniform_location,  m_po_bvec3_uniform_location,
   2467 		m_po_bvec4_uniform_location,   m_po_dmat2_uniform_location,  m_po_dmat2x3_uniform_location,
   2468 		m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location,  m_po_dmat3x2_uniform_location,
   2469 		m_po_dmat3x4_uniform_location, m_po_dmat4_uniform_location,  m_po_dmat4x2_uniform_location,
   2470 		m_po_dmat4x3_uniform_location, m_po_double_uniform_location, m_po_dvec2_uniform_location,
   2471 		m_po_dvec3_uniform_location,   m_po_dvec4_uniform_location,  m_po_float_uniform_location,
   2472 		m_po_int_uniform_location,	 m_po_ivec2_uniform_location,  m_po_ivec3_uniform_location,
   2473 		m_po_ivec4_uniform_location,   m_po_uint_uniform_location,   m_po_uvec2_uniform_location,
   2474 		m_po_uvec3_uniform_location,   m_po_uvec4_uniform_location,  m_po_vec2_uniform_location,
   2475 		m_po_vec3_uniform_location,	m_po_vec4_uniform_location
   2476 	};
   2477 
   2478 	const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
   2479 	const unsigned int n_uniforms		   = sizeof(uniforms) / sizeof(uniforms[0]);
   2480 
   2481 	for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
   2482 	{
   2483 		_uniform_function uniform_function = uniform_functions[n_uniform_function];
   2484 
   2485 		for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
   2486 		{
   2487 			glw::GLint uniform_location = uniforms[n_uniform];
   2488 
   2489 			/* Make sure we only use glUniformMatrix*() functions with matrix uniforms,
   2490 			 * and glUniform*() functions with vector uniforms.
   2491 			 */
   2492 			bool is_matrix_uniform = isMatrixUniform(uniform_location);
   2493 
   2494 			if (((false == is_matrix_uniform) && (true == isMatrixUniformFunction(uniform_function))) ||
   2495 				((true == is_matrix_uniform) && (false == isMatrixUniformFunction(uniform_function))))
   2496 			{
   2497 				continue;
   2498 			}
   2499 
   2500 			/* Issue the call with an invalid <count> argument */
   2501 			switch (uniform_function)
   2502 			{
   2503 			case UNIFORM_FUNCTION_1DV:
   2504 				gl.uniform1dv(uniform_location, 2, double_values);
   2505 				break;
   2506 			case UNIFORM_FUNCTION_2DV:
   2507 				gl.uniform2dv(uniform_location, 2, double_values);
   2508 				break;
   2509 			case UNIFORM_FUNCTION_3DV:
   2510 				gl.uniform3dv(uniform_location, 2, double_values);
   2511 				break;
   2512 			case UNIFORM_FUNCTION_4DV:
   2513 				gl.uniform4dv(uniform_location, 2, double_values);
   2514 				break;
   2515 			case UNIFORM_FUNCTION_MATRIX2DV:
   2516 				gl.uniformMatrix2dv(uniform_location, 2, GL_FALSE, double_values);
   2517 				break;
   2518 			case UNIFORM_FUNCTION_MATRIX2X3DV:
   2519 				gl.uniformMatrix2x3dv(uniform_location, 2, GL_FALSE, double_values);
   2520 				break;
   2521 			case UNIFORM_FUNCTION_MATRIX2X4DV:
   2522 				gl.uniformMatrix2x4dv(uniform_location, 2, GL_FALSE, double_values);
   2523 				break;
   2524 			case UNIFORM_FUNCTION_MATRIX3DV:
   2525 				gl.uniformMatrix3dv(uniform_location, 2, GL_FALSE, double_values);
   2526 				break;
   2527 			case UNIFORM_FUNCTION_MATRIX3X2DV:
   2528 				gl.uniformMatrix3x2dv(uniform_location, 2, GL_FALSE, double_values);
   2529 				break;
   2530 			case UNIFORM_FUNCTION_MATRIX3X4DV:
   2531 				gl.uniformMatrix3x4dv(uniform_location, 2, GL_FALSE, double_values);
   2532 				break;
   2533 			case UNIFORM_FUNCTION_MATRIX4DV:
   2534 				gl.uniformMatrix4dv(uniform_location, 2, GL_FALSE, double_values);
   2535 				break;
   2536 			case UNIFORM_FUNCTION_MATRIX4X2DV:
   2537 				gl.uniformMatrix4x2dv(uniform_location, 2, GL_FALSE, double_values);
   2538 				break;
   2539 			case UNIFORM_FUNCTION_MATRIX4X3DV:
   2540 				gl.uniformMatrix4x3dv(uniform_location, 2, GL_FALSE, double_values);
   2541 				break;
   2542 
   2543 			default:
   2544 			{
   2545 				TCU_FAIL("Unrecognized uniform function");
   2546 			}
   2547 			} /* switch (uniform_function) */
   2548 
   2549 			/* Make sure GL_INVALID_VALUE was generated */
   2550 			glw::GLenum error_code = gl.getError();
   2551 
   2552 			if (error_code != GL_INVALID_OPERATION)
   2553 			{
   2554 				m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
   2555 								   << "() "
   2556 									  "was called with an invalid count argument but did not generate a "
   2557 									  "GL_INVALID_OPERATION error"
   2558 								   << tcu::TestLog::EndMessage;
   2559 
   2560 				result = false;
   2561 			}
   2562 		} /* for (all non-arrayed uniforms) */
   2563 	}	 /* for (all uniform functions) */
   2564 
   2565 	return result;
   2566 }
   2567 
   2568 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
   2569  *  glUniformMatrix*dv() functions is used to load an uniform at an invalid location.
   2570  *
   2571  *  @return true if the implementation was found to behave as expected, false otherwise.
   2572  **/
   2573 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation()
   2574 {
   2575 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   2576 	bool				  result = true;
   2577 
   2578 	/* Find the largest valid uniform location */
   2579 	const glw::GLint uniform_locations[] = {
   2580 		m_po_bool_arr_uniform_location,	m_po_bool_uniform_location,		  m_po_bvec2_arr_uniform_location,
   2581 		m_po_bvec2_uniform_location,	   m_po_bvec3_arr_uniform_location,   m_po_bvec3_uniform_location,
   2582 		m_po_bvec4_arr_uniform_location,   m_po_bvec4_uniform_location,		  m_po_dmat2_arr_uniform_location,
   2583 		m_po_dmat2_uniform_location,	   m_po_dmat2x3_arr_uniform_location, m_po_dmat2x3_uniform_location,
   2584 		m_po_dmat2x4_arr_uniform_location, m_po_dmat2x4_uniform_location,	 m_po_dmat3_arr_uniform_location,
   2585 		m_po_dmat3_uniform_location,	   m_po_dmat3x2_arr_uniform_location, m_po_dmat3x2_uniform_location,
   2586 		m_po_dmat3x4_arr_uniform_location, m_po_dmat3x4_uniform_location,	 m_po_dmat4_arr_uniform_location,
   2587 		m_po_dmat4_uniform_location,	   m_po_dmat4x2_arr_uniform_location, m_po_dmat4x2_uniform_location,
   2588 		m_po_dmat4x3_arr_uniform_location, m_po_dmat4x3_uniform_location,	 m_po_double_arr_uniform_location,
   2589 		m_po_double_uniform_location,	  m_po_dvec2_arr_uniform_location,   m_po_dvec2_uniform_location,
   2590 		m_po_dvec3_arr_uniform_location,   m_po_dvec3_uniform_location,		  m_po_dvec4_arr_uniform_location,
   2591 		m_po_dvec4_uniform_location,	   m_po_float_arr_uniform_location,   m_po_float_uniform_location,
   2592 		m_po_int_arr_uniform_location,	 m_po_int_uniform_location,		  m_po_ivec2_arr_uniform_location,
   2593 		m_po_ivec2_uniform_location,	   m_po_ivec3_arr_uniform_location,   m_po_ivec3_uniform_location,
   2594 		m_po_ivec4_arr_uniform_location,   m_po_ivec4_uniform_location,		  m_po_uint_arr_uniform_location,
   2595 		m_po_uint_uniform_location,		   m_po_uvec2_arr_uniform_location,   m_po_uvec2_uniform_location,
   2596 		m_po_uvec3_arr_uniform_location,   m_po_uvec3_uniform_location,		  m_po_uvec4_arr_uniform_location,
   2597 		m_po_uvec4_uniform_location,	   m_po_vec2_arr_uniform_location,	m_po_vec2_uniform_location,
   2598 		m_po_vec3_arr_uniform_location,	m_po_vec3_uniform_location,		  m_po_vec4_arr_uniform_location,
   2599 		m_po_vec4_uniform_location
   2600 	};
   2601 	const unsigned int n_uniform_locations	= sizeof(uniform_locations) / sizeof(uniform_locations[0]);
   2602 	glw::GLint		   valid_uniform_location = -1;
   2603 
   2604 	for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
   2605 	{
   2606 		glw::GLint uniform_location = uniform_locations[n_uniform_location];
   2607 
   2608 		if (uniform_location > valid_uniform_location)
   2609 		{
   2610 			valid_uniform_location = uniform_location;
   2611 		}
   2612 	} /* for (all  uniform locations) */
   2613 
   2614 	/* Iterate through all uniform functions and make sure GL_INVALID_OPERATION error is always generated
   2615 	 * for invalid uniform location that is != -1
   2616 	 */
   2617 	const double double_data[] = {
   2618 		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
   2619 	};
   2620 	const glw::GLint invalid_uniform_location = valid_uniform_location + 1;
   2621 
   2622 	for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
   2623 		 ++n_uniform_function)
   2624 	{
   2625 		_uniform_function uniform_function = (_uniform_function)n_uniform_function;
   2626 
   2627 		switch (uniform_function)
   2628 		{
   2629 		case UNIFORM_FUNCTION_1D:
   2630 			gl.uniform1d(invalid_uniform_location, 0.0);
   2631 			break;
   2632 		case UNIFORM_FUNCTION_2D:
   2633 			gl.uniform2d(invalid_uniform_location, 0.0, 1.0);
   2634 			break;
   2635 		case UNIFORM_FUNCTION_3D:
   2636 			gl.uniform3d(invalid_uniform_location, 0.0, 1.0, 2.0);
   2637 			break;
   2638 		case UNIFORM_FUNCTION_4D:
   2639 			gl.uniform4d(invalid_uniform_location, 0.0, 1.0, 2.0, 3.0);
   2640 			break;
   2641 
   2642 		case UNIFORM_FUNCTION_1DV:
   2643 			gl.uniform1dv(invalid_uniform_location, 1 /* count */, double_data);
   2644 			break;
   2645 		case UNIFORM_FUNCTION_2DV:
   2646 			gl.uniform2dv(invalid_uniform_location, 1 /* count */, double_data);
   2647 			break;
   2648 		case UNIFORM_FUNCTION_3DV:
   2649 			gl.uniform3dv(invalid_uniform_location, 1 /* count */, double_data);
   2650 			break;
   2651 		case UNIFORM_FUNCTION_4DV:
   2652 			gl.uniform4dv(invalid_uniform_location, 1 /* count */, double_data);
   2653 			break;
   2654 
   2655 		case UNIFORM_FUNCTION_MATRIX2DV:
   2656 			gl.uniformMatrix2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2657 			break;
   2658 		case UNIFORM_FUNCTION_MATRIX2X3DV:
   2659 			gl.uniformMatrix2x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2660 			break;
   2661 		case UNIFORM_FUNCTION_MATRIX2X4DV:
   2662 			gl.uniformMatrix2x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2663 			break;
   2664 		case UNIFORM_FUNCTION_MATRIX3DV:
   2665 			gl.uniformMatrix3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2666 			break;
   2667 		case UNIFORM_FUNCTION_MATRIX3X2DV:
   2668 			gl.uniformMatrix3x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2669 			break;
   2670 		case UNIFORM_FUNCTION_MATRIX3X4DV:
   2671 			gl.uniformMatrix3x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2672 			break;
   2673 		case UNIFORM_FUNCTION_MATRIX4DV:
   2674 			gl.uniformMatrix4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2675 			break;
   2676 		case UNIFORM_FUNCTION_MATRIX4X2DV:
   2677 			gl.uniformMatrix4x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2678 			break;
   2679 		case UNIFORM_FUNCTION_MATRIX4X3DV:
   2680 			gl.uniformMatrix4x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
   2681 			break;
   2682 
   2683 		default:
   2684 		{
   2685 			TCU_FAIL("Unrecognized uniform function");
   2686 		}
   2687 		}
   2688 
   2689 		const glw::GLenum error_code = gl.getError();
   2690 
   2691 		if (error_code != GL_INVALID_OPERATION)
   2692 		{
   2693 			m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
   2694 							   << "() did not generate an error"
   2695 								  " when passed an invalid uniform location different from -1."
   2696 							   << tcu::TestLog::EndMessage;
   2697 
   2698 			result = false;
   2699 		}
   2700 	} /* for (all uniform functions) */
   2701 
   2702 	return result;
   2703 }
   2704 
   2705 /** Verifies GL_INVALID_VALUE is generated if any of the glUniform*dv() or
   2706  *  glUniformMatrix*dv() functions is used to load a compatible uniform using an
   2707  *  invalid <count> argument of -1.
   2708  *
   2709  *  @return true if the implementation was found to behave as expected, false otherwise.
   2710  **/
   2711 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount()
   2712 {
   2713 	const glw::GLdouble double_values[16] = { 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
   2714 											  9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
   2715 	const glw::Functions&   gl					= m_context.getRenderContext().getFunctions();
   2716 	bool					result				= true;
   2717 	const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV,		  UNIFORM_FUNCTION_2DV,
   2718 													UNIFORM_FUNCTION_3DV,		  UNIFORM_FUNCTION_4DV,
   2719 													UNIFORM_FUNCTION_MATRIX2DV,   UNIFORM_FUNCTION_MATRIX2X3DV,
   2720 													UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
   2721 													UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
   2722 													UNIFORM_FUNCTION_MATRIX4DV,   UNIFORM_FUNCTION_MATRIX4X2DV,
   2723 													UNIFORM_FUNCTION_MATRIX4X3DV };
   2724 	const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
   2725 
   2726 	for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
   2727 	{
   2728 		_uniform_function uniform_function = uniform_functions[n_uniform_function];
   2729 
   2730 		switch (uniform_function)
   2731 		{
   2732 		case UNIFORM_FUNCTION_1DV:
   2733 			gl.uniform1dv(m_po_double_arr_uniform_location, -1, double_values);
   2734 			break;
   2735 		case UNIFORM_FUNCTION_2DV:
   2736 			gl.uniform2dv(m_po_dvec2_arr_uniform_location, -1, double_values);
   2737 			break;
   2738 		case UNIFORM_FUNCTION_3DV:
   2739 			gl.uniform3dv(m_po_dvec3_arr_uniform_location, -1, double_values);
   2740 			break;
   2741 		case UNIFORM_FUNCTION_4DV:
   2742 			gl.uniform4dv(m_po_dvec4_arr_uniform_location, -1, double_values);
   2743 			break;
   2744 		case UNIFORM_FUNCTION_MATRIX2DV:
   2745 			gl.uniformMatrix2dv(m_po_dmat2_arr_uniform_location, -1, GL_FALSE, double_values);
   2746 			break;
   2747 		case UNIFORM_FUNCTION_MATRIX2X3DV:
   2748 			gl.uniformMatrix2x3dv(m_po_dmat2x3_arr_uniform_location, -1, GL_FALSE, double_values);
   2749 			break;
   2750 		case UNIFORM_FUNCTION_MATRIX2X4DV:
   2751 			gl.uniformMatrix2x4dv(m_po_dmat2x4_arr_uniform_location, -1, GL_FALSE, double_values);
   2752 			break;
   2753 		case UNIFORM_FUNCTION_MATRIX3DV:
   2754 			gl.uniformMatrix3dv(m_po_dmat3_arr_uniform_location, -1, GL_FALSE, double_values);
   2755 			break;
   2756 		case UNIFORM_FUNCTION_MATRIX3X2DV:
   2757 			gl.uniformMatrix3x2dv(m_po_dmat3x2_arr_uniform_location, -1, GL_FALSE, double_values);
   2758 			break;
   2759 		case UNIFORM_FUNCTION_MATRIX3X4DV:
   2760 			gl.uniformMatrix3x4dv(m_po_dmat3x4_arr_uniform_location, -1, GL_FALSE, double_values);
   2761 			break;
   2762 		case UNIFORM_FUNCTION_MATRIX4DV:
   2763 			gl.uniformMatrix4dv(m_po_dmat4_arr_uniform_location, -1, GL_FALSE, double_values);
   2764 			break;
   2765 		case UNIFORM_FUNCTION_MATRIX4X2DV:
   2766 			gl.uniformMatrix4x2dv(m_po_dmat4x2_arr_uniform_location, -1, GL_FALSE, double_values);
   2767 			break;
   2768 		case UNIFORM_FUNCTION_MATRIX4X3DV:
   2769 			gl.uniformMatrix4x3dv(m_po_dmat4x3_arr_uniform_location, -1, GL_FALSE, double_values);
   2770 			break;
   2771 
   2772 		default:
   2773 		{
   2774 			TCU_FAIL("Unrecognized uniform function");
   2775 		}
   2776 		} /* switch (uniform_function) */
   2777 
   2778 		/* Make sure GL_INVALID_VALUE was generated */
   2779 		glw::GLenum error_code = gl.getError();
   2780 
   2781 		if (error_code != GL_INVALID_VALUE)
   2782 		{
   2783 			m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
   2784 							   << "() "
   2785 								  "was called with a negative count argument but did not generate a "
   2786 								  "GL_INVALID_VALUE error"
   2787 							   << tcu::TestLog::EndMessage;
   2788 
   2789 			result = false;
   2790 		}
   2791 	} /* for (all uniform functions) */
   2792 
   2793 	return result;
   2794 }
   2795 
   2796 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
   2797  *  glUniformMatrix*dv() functions is used to load an uniform that's incompatible with the
   2798  *  function (as per spec).
   2799  *
   2800  *  @return true if the implementation was found to behave as expected, false otherwise.
   2801  **/
   2802 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions()
   2803 {
   2804 	const double		  double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
   2805 	glw::GLenum			  error_code	= GL_NO_ERROR;
   2806 	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
   2807 	bool				  result		= true;
   2808 
   2809 	const glw::GLint double_uniform_locations[] = { m_po_dmat2_uniform_location,   m_po_dmat2x3_uniform_location,
   2810 													m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location,
   2811 													m_po_dmat3x2_uniform_location, m_po_dmat3x4_uniform_location,
   2812 													m_po_dmat4_uniform_location,   m_po_dmat4x2_uniform_location,
   2813 													m_po_dmat4x3_uniform_location, m_po_double_uniform_location,
   2814 													m_po_dvec2_uniform_location,   m_po_dvec3_uniform_location,
   2815 													m_po_dvec4_uniform_location };
   2816 	const unsigned int n_double_uniform_locations =
   2817 		sizeof(double_uniform_locations) / sizeof(double_uniform_locations[0]);
   2818 
   2819 	gl.useProgram(m_po_id);
   2820 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   2821 
   2822 	for (unsigned int n_uniform_location = 0; n_uniform_location < n_double_uniform_locations; ++n_uniform_location)
   2823 	{
   2824 		glw::GLint uniform_location = double_uniform_locations[n_uniform_location];
   2825 
   2826 		for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
   2827 			 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); function++)
   2828 		{
   2829 			_uniform_function e_function = static_cast<_uniform_function>(function);
   2830 			/* Exclude valid combinations */
   2831 			if (((uniform_location == m_po_dmat2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2DV)) ||
   2832 				((uniform_location == m_po_dmat2x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X3DV)) ||
   2833 				((uniform_location == m_po_dmat2x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X4DV)) ||
   2834 				((uniform_location == m_po_dmat3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3DV)) ||
   2835 				((uniform_location == m_po_dmat3x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X2DV)) ||
   2836 				((uniform_location == m_po_dmat3x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X4DV)) ||
   2837 				((uniform_location == m_po_dmat4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4DV)) ||
   2838 				((uniform_location == m_po_dmat4x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X2DV)) ||
   2839 				((uniform_location == m_po_dmat4x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X3DV)) ||
   2840 				((uniform_location == m_po_double_uniform_location) &&
   2841 				 ((e_function == UNIFORM_FUNCTION_1D) || (e_function == UNIFORM_FUNCTION_1DV))) ||
   2842 				((uniform_location == m_po_dvec2_uniform_location) &&
   2843 				 ((e_function == UNIFORM_FUNCTION_2D) || (e_function == UNIFORM_FUNCTION_2DV))) ||
   2844 				((uniform_location == m_po_dvec3_uniform_location) &&
   2845 				 ((e_function == UNIFORM_FUNCTION_3D) || (e_function == UNIFORM_FUNCTION_3DV))) ||
   2846 				((uniform_location == m_po_dvec4_uniform_location) &&
   2847 				 ((e_function == UNIFORM_FUNCTION_4D) || (e_function == UNIFORM_FUNCTION_4DV))))
   2848 			{
   2849 				continue;
   2850 			}
   2851 
   2852 			switch (e_function)
   2853 			{
   2854 			case UNIFORM_FUNCTION_1D:
   2855 			{
   2856 				gl.uniform1d(uniform_location, double_data[0]);
   2857 
   2858 				break;
   2859 			}
   2860 
   2861 			case UNIFORM_FUNCTION_2D:
   2862 			{
   2863 				gl.uniform2d(uniform_location, double_data[0], double_data[1]);
   2864 
   2865 				break;
   2866 			}
   2867 
   2868 			case UNIFORM_FUNCTION_3D:
   2869 			{
   2870 				gl.uniform3d(uniform_location, double_data[0], double_data[1], double_data[2]);
   2871 
   2872 				break;
   2873 			}
   2874 
   2875 			case UNIFORM_FUNCTION_4D:
   2876 			{
   2877 				gl.uniform4d(uniform_location, double_data[0], double_data[1], double_data[2], double_data[3]);
   2878 
   2879 				break;
   2880 			}
   2881 
   2882 			case UNIFORM_FUNCTION_1DV:
   2883 				gl.uniform1dv(uniform_location, 1 /* count */, double_data);
   2884 				break;
   2885 			case UNIFORM_FUNCTION_2DV:
   2886 				gl.uniform2dv(uniform_location, 1 /* count */, double_data);
   2887 				break;
   2888 			case UNIFORM_FUNCTION_3DV:
   2889 				gl.uniform3dv(uniform_location, 1 /* count */, double_data);
   2890 				break;
   2891 			case UNIFORM_FUNCTION_4DV:
   2892 				gl.uniform4dv(uniform_location, 1 /* count */, double_data);
   2893 				break;
   2894 			case UNIFORM_FUNCTION_MATRIX2DV:
   2895 				gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2896 				break;
   2897 			case UNIFORM_FUNCTION_MATRIX2X3DV:
   2898 				gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2899 				break;
   2900 			case UNIFORM_FUNCTION_MATRIX2X4DV:
   2901 				gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2902 				break;
   2903 			case UNIFORM_FUNCTION_MATRIX3DV:
   2904 				gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2905 				break;
   2906 			case UNIFORM_FUNCTION_MATRIX3X2DV:
   2907 				gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2908 				break;
   2909 			case UNIFORM_FUNCTION_MATRIX3X4DV:
   2910 				gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2911 				break;
   2912 			case UNIFORM_FUNCTION_MATRIX4DV:
   2913 				gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2914 				break;
   2915 			case UNIFORM_FUNCTION_MATRIX4X2DV:
   2916 				gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2917 				break;
   2918 			case UNIFORM_FUNCTION_MATRIX4X3DV:
   2919 				gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
   2920 				break;
   2921 
   2922 			default:
   2923 			{
   2924 				TCU_FAIL("Unrecognized function");
   2925 			}
   2926 			} /* switch (function) */
   2927 
   2928 			/* Make sure GL_INVALID_OPERATION error was generated */
   2929 			error_code = gl.getError();
   2930 
   2931 			if (error_code != GL_INVALID_OPERATION)
   2932 			{
   2933 				m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error [" << error_code
   2934 								   << "] was generated when a mismatched "
   2935 									  "double-precision uniform function "
   2936 								   << getUniformFunctionString(e_function) << "() was used to configure uniform "
   2937 								   << getUniformNameForLocation(uniform_location) << "." << tcu::TestLog::EndMessage;
   2938 
   2939 				result = false;
   2940 			}
   2941 		} /* for (all uniform functions) */
   2942 	}	 /* for (all uniform locations) */
   2943 
   2944 	return result;
   2945 }
   2946 
   2947 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
   2948  *  glUniform*dv() functions is used to load an uniform, size of which is incompatible
   2949  *  with the function.
   2950  *
   2951  *  @return true if the implementation was found to behave as expected, false otherwise.
   2952  **/
   2953 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions()
   2954 {
   2955 	const double		  double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
   2956 	glw::GLenum			  error_code	= GL_NO_ERROR;
   2957 	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
   2958 	bool				  result		= true;
   2959 
   2960 	const int data[] = {
   2961 		/* API function */ /* Uniform location */ /* Count (dv functions only) */
   2962 		(int)UNIFORM_FUNCTION_2D, m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_2DV,
   2963 		m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_double_uniform_location, 0,
   2964 		(int)UNIFORM_FUNCTION_3DV, m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
   2965 		m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_double_uniform_location, 2,
   2966 		(int)UNIFORM_FUNCTION_1D, m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
   2967 		m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_dvec2_uniform_location, 0,
   2968 		(int)UNIFORM_FUNCTION_3DV, m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
   2969 		m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec2_uniform_location, 2,
   2970 		(int)UNIFORM_FUNCTION_1D, m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
   2971 		m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec3_uniform_location, 0,
   2972 		(int)UNIFORM_FUNCTION_2DV, m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
   2973 		m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec3_uniform_location, 2,
   2974 		(int)UNIFORM_FUNCTION_1D, m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
   2975 		m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec4_uniform_location, 0,
   2976 		(int)UNIFORM_FUNCTION_2DV, m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_3D,
   2977 		m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_3DV, m_po_dvec4_uniform_location, 2,
   2978 	};
   2979 	const unsigned int n_checks = sizeof(data) / sizeof(data[0]) / 3 /* entries per row */;
   2980 
   2981 	gl.useProgram(m_po_id);
   2982 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   2983 
   2984 	for (unsigned int n_check = 0; n_check < n_checks; ++n_check)
   2985 	{
   2986 		_uniform_function function		   = (_uniform_function)data[n_check * 3 + 0];
   2987 		int				  uniform_location = data[n_check * 3 + 1];
   2988 		int				  uniform_count	= data[n_check * 3 + 2];
   2989 
   2990 		switch (function)
   2991 		{
   2992 		case UNIFORM_FUNCTION_1D:
   2993 			gl.uniform1d(uniform_location, 0.0);
   2994 			break;
   2995 		case UNIFORM_FUNCTION_1DV:
   2996 			gl.uniform1dv(uniform_location, uniform_count, double_data);
   2997 			break;
   2998 		case UNIFORM_FUNCTION_2D:
   2999 			gl.uniform2d(uniform_location, 0.0, 1.0);
   3000 			break;
   3001 		case UNIFORM_FUNCTION_2DV:
   3002 			gl.uniform2dv(uniform_location, uniform_count, double_data);
   3003 			break;
   3004 		case UNIFORM_FUNCTION_3D:
   3005 			gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
   3006 			break;
   3007 		case UNIFORM_FUNCTION_3DV:
   3008 			gl.uniform3dv(uniform_location, uniform_count, double_data);
   3009 			break;
   3010 		case UNIFORM_FUNCTION_4D:
   3011 			gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
   3012 			break;
   3013 		case UNIFORM_FUNCTION_4DV:
   3014 			gl.uniform4dv(uniform_location, uniform_count, double_data);
   3015 			break;
   3016 
   3017 		default:
   3018 		{
   3019 			DE_ASSERT(false);
   3020 		}
   3021 		} /* switch (function) */
   3022 
   3023 		error_code = gl.getError();
   3024 		if (error_code != GL_INVALID_OPERATION)
   3025 		{
   3026 			m_testCtx.getLog() << tcu::TestLog::Message << getUniformFunctionString(function)
   3027 							   << "() function did not generate GL_INVALID_OPERATION error when called for"
   3028 								  " a uniform of incompatible size. (check index: "
   3029 							   << n_check << ")" << tcu::TestLog::EndMessage;
   3030 
   3031 			result = false;
   3032 		}
   3033 	} /* for (all checks) */
   3034 
   3035 	return result;
   3036 }
   3037 
   3038 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
   3039  *  glUniform*dv() functions is used to load an uniform, type of which is incompatible
   3040  *  with the function.
   3041  *
   3042  *  @return true if the implementation was found to behave as expected, false otherwise.
   3043  **/
   3044 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions()
   3045 {
   3046 	const double		  double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
   3047 	glw::GLenum			  error_code	= GL_NO_ERROR;
   3048 	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
   3049 	bool				  result		= true;
   3050 
   3051 	const glw::GLint nondouble_uniform_locations[] = { m_po_bool_uniform_location,  m_po_bvec2_uniform_location,
   3052 													   m_po_bvec3_uniform_location, m_po_bvec4_uniform_location,
   3053 													   m_po_float_uniform_location, m_po_int_uniform_location,
   3054 													   m_po_ivec2_uniform_location, m_po_ivec3_uniform_location,
   3055 													   m_po_ivec4_uniform_location, m_po_uint_uniform_location,
   3056 													   m_po_uvec2_uniform_location, m_po_uvec3_uniform_location,
   3057 													   m_po_uvec4_uniform_location, m_po_vec2_uniform_location,
   3058 													   m_po_vec3_uniform_location,  m_po_vec4_uniform_location };
   3059 	const unsigned int n_nondouble_uniform_locations =
   3060 		sizeof(nondouble_uniform_locations) / sizeof(nondouble_uniform_locations[0]);
   3061 
   3062 	gl.useProgram(m_po_id);
   3063 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   3064 
   3065 	for (unsigned int n_uniform_location = 0; n_uniform_location < n_nondouble_uniform_locations; ++n_uniform_location)
   3066 	{
   3067 		glw::GLint uniform_location = nondouble_uniform_locations[n_uniform_location];
   3068 
   3069 		for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
   3070 			 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); ++function)
   3071 		{
   3072 			switch (static_cast<_uniform_function>(function))
   3073 			{
   3074 			case UNIFORM_FUNCTION_1D:
   3075 				gl.uniform1d(uniform_location, 0.0);
   3076 				break;
   3077 			case UNIFORM_FUNCTION_1DV:
   3078 				gl.uniform1dv(uniform_location, 1, double_data);
   3079 				break;
   3080 			case UNIFORM_FUNCTION_2D:
   3081 				gl.uniform2d(uniform_location, 0.0, 1.0);
   3082 				break;
   3083 			case UNIFORM_FUNCTION_2DV:
   3084 				gl.uniform2dv(uniform_location, 1, double_data);
   3085 				break;
   3086 			case UNIFORM_FUNCTION_3D:
   3087 				gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
   3088 				break;
   3089 			case UNIFORM_FUNCTION_3DV:
   3090 				gl.uniform3dv(uniform_location, 1, double_data);
   3091 				break;
   3092 			case UNIFORM_FUNCTION_4D:
   3093 				gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
   3094 				break;
   3095 			case UNIFORM_FUNCTION_4DV:
   3096 				gl.uniform4dv(uniform_location, 1, double_data);
   3097 				break;
   3098 
   3099 			case UNIFORM_FUNCTION_MATRIX2DV:
   3100 				gl.uniformMatrix2dv(uniform_location, 1, GL_FALSE, double_data);
   3101 				break;
   3102 			case UNIFORM_FUNCTION_MATRIX2X3DV:
   3103 				gl.uniformMatrix2x3dv(uniform_location, 1, GL_FALSE, double_data);
   3104 				break;
   3105 			case UNIFORM_FUNCTION_MATRIX2X4DV:
   3106 				gl.uniformMatrix2x4dv(uniform_location, 1, GL_FALSE, double_data);
   3107 				break;
   3108 			case UNIFORM_FUNCTION_MATRIX3DV:
   3109 				gl.uniformMatrix3dv(uniform_location, 1, GL_FALSE, double_data);
   3110 				break;
   3111 			case UNIFORM_FUNCTION_MATRIX3X2DV:
   3112 				gl.uniformMatrix3x2dv(uniform_location, 1, GL_FALSE, double_data);
   3113 				break;
   3114 			case UNIFORM_FUNCTION_MATRIX3X4DV:
   3115 				gl.uniformMatrix3x4dv(uniform_location, 1, GL_FALSE, double_data);
   3116 				break;
   3117 			case UNIFORM_FUNCTION_MATRIX4DV:
   3118 				gl.uniformMatrix4dv(uniform_location, 1, GL_FALSE, double_data);
   3119 				break;
   3120 			case UNIFORM_FUNCTION_MATRIX4X2DV:
   3121 				gl.uniformMatrix4x2dv(uniform_location, 1, GL_FALSE, double_data);
   3122 				break;
   3123 			case UNIFORM_FUNCTION_MATRIX4X3DV:
   3124 				gl.uniformMatrix4x3dv(uniform_location, 1, GL_FALSE, double_data);
   3125 				break;
   3126 
   3127 			default:
   3128 			{
   3129 				DE_ASSERT(false);
   3130 			}
   3131 			} /* switch (function) */
   3132 
   3133 			error_code = gl.getError();
   3134 			if (error_code != GL_INVALID_OPERATION)
   3135 			{
   3136 				m_testCtx.getLog() << tcu::TestLog::Message
   3137 								   << getUniformFunctionString(static_cast<_uniform_function>(function))
   3138 								   << "() function did not generate GL_INVALID_OPERATION error when called for"
   3139 									  " a uniform of incompatible type."
   3140 								   << tcu::TestLog::EndMessage;
   3141 
   3142 				result = false;
   3143 			}
   3144 		}
   3145 	} /* for (all checks) */
   3146 
   3147 	return result;
   3148 }
   3149 
   3150 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
   3151  *  glUniform*dv() functions are called without a bound program object.
   3152  *
   3153  *  @return true if the implementation was found to behave as expected, false otherwise.
   3154  **/
   3155 bool GPUShaderFP64Test1::verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO()
   3156 {
   3157 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   3158 	bool				  result = true;
   3159 
   3160 	for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST); function < static_cast<int>(UNIFORM_FUNCTION_COUNT);
   3161 		 function++)
   3162 	{
   3163 		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 };
   3164 
   3165 		switch (static_cast<_uniform_function>(function))
   3166 		{
   3167 		case UNIFORM_FUNCTION_1D:
   3168 			gl.uniform1d(m_po_double_uniform_location, 0.0);
   3169 			break;
   3170 		case UNIFORM_FUNCTION_1DV:
   3171 			gl.uniform1dv(m_po_double_uniform_location, 1, data);
   3172 			break;
   3173 		case UNIFORM_FUNCTION_2D:
   3174 			gl.uniform2d(m_po_dvec2_uniform_location, 0.0, 1.0);
   3175 			break;
   3176 		case UNIFORM_FUNCTION_2DV:
   3177 			gl.uniform2dv(m_po_dvec2_uniform_location, 1, data);
   3178 			break;
   3179 		case UNIFORM_FUNCTION_3D:
   3180 			gl.uniform3d(m_po_dvec3_uniform_location, 0.0, 1.0, 2.0);
   3181 			break;
   3182 		case UNIFORM_FUNCTION_3DV:
   3183 			gl.uniform3dv(m_po_dvec3_uniform_location, 1, data);
   3184 			break;
   3185 		case UNIFORM_FUNCTION_4D:
   3186 			gl.uniform4d(m_po_dvec4_uniform_location, 0.0, 1.0, 2.0, 3.0);
   3187 			break;
   3188 		case UNIFORM_FUNCTION_4DV:
   3189 			gl.uniform4dv(m_po_dvec4_uniform_location, 1, data);
   3190 			break;
   3191 
   3192 		case UNIFORM_FUNCTION_MATRIX2DV:
   3193 			gl.uniformMatrix2dv(m_po_dmat2_uniform_location, 1, GL_FALSE /* transpose */, data);
   3194 			break;
   3195 		case UNIFORM_FUNCTION_MATRIX2X3DV:
   3196 			gl.uniformMatrix2x3dv(m_po_dmat2x3_uniform_location, 1, GL_FALSE /* transpose */, data);
   3197 			break;
   3198 		case UNIFORM_FUNCTION_MATRIX2X4DV:
   3199 			gl.uniformMatrix2x4dv(m_po_dmat2x4_uniform_location, 1, GL_FALSE /* transpose */, data);
   3200 			break;
   3201 		case UNIFORM_FUNCTION_MATRIX3DV:
   3202 			gl.uniformMatrix3dv(m_po_dmat3_uniform_location, 1, GL_FALSE /* transpose */, data);
   3203 			break;
   3204 		case UNIFORM_FUNCTION_MATRIX3X2DV:
   3205 			gl.uniformMatrix3x2dv(m_po_dmat3x2_uniform_location, 1, GL_FALSE /* transpose */, data);
   3206 			break;
   3207 		case UNIFORM_FUNCTION_MATRIX3X4DV:
   3208 			gl.uniformMatrix3x4dv(m_po_dmat3x4_uniform_location, 1, GL_FALSE /* transpose */, data);
   3209 			break;
   3210 		case UNIFORM_FUNCTION_MATRIX4DV:
   3211 			gl.uniformMatrix4dv(m_po_dmat4_uniform_location, 1, GL_FALSE /* transpose */, data);
   3212 			break;
   3213 		case UNIFORM_FUNCTION_MATRIX4X2DV:
   3214 			gl.uniformMatrix4x2dv(m_po_dmat4x2_uniform_location, 1, GL_FALSE /* transpose */, data);
   3215 			break;
   3216 		case UNIFORM_FUNCTION_MATRIX4X3DV:
   3217 			gl.uniformMatrix4x3dv(m_po_dmat4x3_uniform_location, 1, GL_FALSE /* transpose */, data);
   3218 			break;
   3219 
   3220 		default:
   3221 		{
   3222 			TCU_FAIL("Unrecognized uniform function");
   3223 		}
   3224 		} /* switch (func) */
   3225 
   3226 		/* Query the error code */
   3227 		glw::GLenum error_code = gl.getError();
   3228 
   3229 		if (error_code != GL_INVALID_OPERATION)
   3230 		{
   3231 			m_testCtx.getLog() << tcu::TestLog::Message << "Implementation did not return GL_INVALID_OPERATION when "
   3232 							   << getUniformFunctionString(static_cast<_uniform_function>(function))
   3233 							   << "() was called without an active program object" << tcu::TestLog::EndMessage;
   3234 
   3235 			result = false;
   3236 		}
   3237 	} /* for (all uniform functions) */
   3238 
   3239 	return result;
   3240 }
   3241 
   3242 /* Defeinitions of static const symbols declared in GPUShaderFP64Test2 */
   3243 const glw::GLuint GPUShaderFP64Test2::m_n_captured_results = 1024;
   3244 const glw::GLint  GPUShaderFP64Test2::m_result_failure	 = 2;
   3245 const glw::GLint  GPUShaderFP64Test2::m_result_success	 = 1;
   3246 const glw::GLuint GPUShaderFP64Test2::m_texture_width	  = 32;
   3247 const glw::GLuint GPUShaderFP64Test2::m_texture_height	 = m_n_captured_results / m_texture_width;
   3248 const glw::GLuint GPUShaderFP64Test2::m_transform_feedback_buffer_size =
   3249 	m_n_captured_results * sizeof(captured_varying_type);
   3250 const glw::GLchar* GPUShaderFP64Test2::m_uniform_block_name				  = "UniformBlock";
   3251 const glw::GLenum  GPUShaderFP64Test2::ARB_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263;
   3252 
   3253 /** Constructor
   3254  *
   3255  * @param context Test context
   3256  **/
   3257 GPUShaderFP64Test2::GPUShaderFP64Test2(deqp::Context& context)
   3258 	: TestCase(context, "max_uniform_components",
   3259 			   "Verifies that maximum allowed uniform components can be used as double-precision float types")
   3260 	, m_pDispatchCompute(0)
   3261 	, m_framebuffer_id(0)
   3262 	, m_texture_id(0)
   3263 	, m_transform_feedback_buffer_id(0)
   3264 	, m_uniform_buffer_id(0)
   3265 	, m_vertex_array_object_id(0)
   3266 {
   3267 	/* Nothing to be done */
   3268 }
   3269 
   3270 /** Deinitialize test
   3271  *
   3272  **/
   3273 void GPUShaderFP64Test2::deinit()
   3274 {
   3275 	/* GL entry points */
   3276 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3277 
   3278 	/* Clean frambuffer */
   3279 	if (0 != m_framebuffer_id)
   3280 	{
   3281 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
   3282 		gl.deleteFramebuffers(1, &m_framebuffer_id);
   3283 		m_framebuffer_id = 0;
   3284 	}
   3285 
   3286 	/* Clean texture */
   3287 	if (0 != m_texture_id)
   3288 	{
   3289 		gl.bindTexture(GL_TEXTURE_2D, 0);
   3290 		gl.bindImageTexture(0 /* unit */, 0 /* texture */, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
   3291 							GL_READ_ONLY, GL_RGBA8);
   3292 		gl.deleteTextures(1, &m_texture_id);
   3293 		m_texture_id = 0;
   3294 	}
   3295 
   3296 	/* Clean buffers */
   3297 	if (0 != m_transform_feedback_buffer_id)
   3298 	{
   3299 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
   3300 		gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
   3301 		m_transform_feedback_buffer_id = 0;
   3302 	}
   3303 
   3304 	if (0 != m_uniform_buffer_id)
   3305 	{
   3306 		gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
   3307 		gl.deleteBuffers(1, &m_uniform_buffer_id);
   3308 		m_uniform_buffer_id = 0;
   3309 	}
   3310 
   3311 	/* Clean VAO */
   3312 	if (0 != m_vertex_array_object_id)
   3313 	{
   3314 		gl.bindVertexArray(0);
   3315 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
   3316 		m_vertex_array_object_id = 0;
   3317 	}
   3318 }
   3319 
   3320 /** Execute test
   3321  *
   3322  * @return tcu::TestNode::STOP
   3323  **/
   3324 tcu::TestNode::IterateResult GPUShaderFP64Test2::iterate()
   3325 {
   3326 	bool result = true;
   3327 
   3328 	/* Check if extension is supported */
   3329 	if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
   3330 	{
   3331 		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
   3332 	}
   3333 
   3334 	/* Initialize test */
   3335 	testInit();
   3336 
   3337 	prepareShaderStages();
   3338 	prepareUniformTypes();
   3339 
   3340 	/* For all shaders and uniform type combinations */
   3341 	for (std::vector<shaderStage>::const_iterator shader_stage = m_shader_stages.begin();
   3342 		 m_shader_stages.end() != shader_stage; ++shader_stage)
   3343 	{
   3344 		for (std::vector<uniformTypeDetails>::const_iterator uniform_type = m_uniform_types.begin();
   3345 			 m_uniform_types.end() != uniform_type; ++uniform_type)
   3346 		{
   3347 			/* Execute test */
   3348 			if (false == test(*shader_stage, *uniform_type))
   3349 			{
   3350 				result = false;
   3351 			}
   3352 		}
   3353 	}
   3354 
   3355 	/* Set result */
   3356 	if (true == result)
   3357 	{
   3358 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3359 	}
   3360 	else
   3361 	{
   3362 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3363 	}
   3364 
   3365 	/* Done */
   3366 	return tcu::TestNode::STOP;
   3367 }
   3368 
   3369 /** Constructor
   3370  *
   3371  * @param n_columns Number of columns
   3372  * @param n_rows    Number of rows
   3373  **/
   3374 GPUShaderFP64Test2::uniformTypeDetails::uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows)
   3375 	: m_n_columns(n_columns), m_n_rows(n_rows)
   3376 {
   3377 	Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows);
   3378 
   3379 	m_type_name = Utils::getVariableTypeString(type);
   3380 	m_type		= Utils::getGLDataTypeOfVariableType(type);
   3381 }
   3382 
   3383 /** Get primitive type captured with transform feedback
   3384  *
   3385  * @param shader_stage Tested shader stage id
   3386  *
   3387  * @return Primitive type
   3388  **/
   3389 glw::GLenum GPUShaderFP64Test2::getCapturedPrimitiveType(shaderStage shader_stage) const
   3390 {
   3391 	switch (shader_stage)
   3392 	{
   3393 	case GEOMETRY_SHADER:
   3394 	case TESS_CTRL_SHADER:
   3395 	case TESS_EVAL_SHADER:
   3396 	case VERTEX_SHADER:
   3397 		return GL_POINTS;
   3398 		break;
   3399 
   3400 	default:
   3401 		return GL_NONE;
   3402 		break;
   3403 	}
   3404 }
   3405 
   3406 /** Get primitive type drawn with DrawArrays
   3407  *
   3408  * @param shader_stage Tested shader stage id
   3409  *
   3410  * @return Primitive type
   3411  **/
   3412 glw::GLenum GPUShaderFP64Test2::getDrawPrimitiveType(shaderStage shader_stage) const
   3413 {
   3414 	switch (shader_stage)
   3415 	{
   3416 	case FRAGMENT_SHADER:
   3417 		return GL_TRIANGLE_FAN;
   3418 		break;
   3419 
   3420 	case GEOMETRY_SHADER:
   3421 	case VERTEX_SHADER:
   3422 		return GL_POINTS;
   3423 		break;
   3424 
   3425 	case TESS_CTRL_SHADER:
   3426 	case TESS_EVAL_SHADER:
   3427 		return GL_PATCHES;
   3428 		break;
   3429 
   3430 	default:
   3431 		return GL_NONE;
   3432 		break;
   3433 	}
   3434 }
   3435 
   3436 /** Get maximum allowed number of uniform components
   3437  *
   3438  * @param shader_stage Tested shader stage id
   3439  *
   3440  * @return Maxmimum uniform components
   3441  **/
   3442 glw::GLuint GPUShaderFP64Test2::getMaxUniformComponents(shaderStage shader_stage) const
   3443 {
   3444 	const glw::Functions& gl					 = m_context.getRenderContext().getFunctions();
   3445 	glw::GLint			  max_uniform_components = 0;
   3446 	glw::GLenum			  pname					 = 0;
   3447 
   3448 	switch (shader_stage)
   3449 	{
   3450 	case COMPUTE_SHADER:
   3451 		pname = ARB_MAX_COMPUTE_UNIFORM_COMPONENTS;
   3452 		break;
   3453 	case FRAGMENT_SHADER:
   3454 		pname = GL_MAX_FRAGMENT_UNIFORM_COMPONENTS;
   3455 		break;
   3456 	case GEOMETRY_SHADER:
   3457 		pname = GL_MAX_GEOMETRY_UNIFORM_COMPONENTS;
   3458 		break;
   3459 	case TESS_CTRL_SHADER:
   3460 		pname = GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS;
   3461 		break;
   3462 	case TESS_EVAL_SHADER:
   3463 		pname = GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS;
   3464 		break;
   3465 	case VERTEX_SHADER:
   3466 		pname = GL_MAX_VERTEX_UNIFORM_COMPONENTS;
   3467 		break;
   3468 	}
   3469 
   3470 	gl.getIntegerv(pname, &max_uniform_components);
   3471 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
   3472 
   3473 	return max_uniform_components;
   3474 }
   3475 
   3476 /** Get maximum size allowed for an uniform block
   3477  *
   3478  * @return Maxmimum uniform block size
   3479  **/
   3480 glw::GLuint GPUShaderFP64Test2::getMaxUniformBlockSize() const
   3481 {
   3482 	const glw::Functions& gl					 = m_context.getRenderContext().getFunctions();
   3483 	glw::GLint			  max_uniform_block_size = 0;
   3484 
   3485 	gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_block_size);
   3486 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
   3487 
   3488 	return max_uniform_block_size;
   3489 }
   3490 
   3491 /** Get number of components required to store single uniform of given type
   3492  *
   3493  * @param uniform_type Tested uniform type
   3494  *
   3495  * @return Number of components
   3496  **/
   3497 glw::GLuint GPUShaderFP64Test2::getRequiredComponentsNumber(const uniformTypeDetails& uniform_type) const
   3498 {
   3499 	static const glw::GLuint type_size	 = 2; /* double takes 2 N */
   3500 	const glw::GLuint		 column_length = uniform_type.m_n_rows;
   3501 
   3502 	if (1 == uniform_type.m_n_columns)
   3503 	{
   3504 		return type_size * column_length;
   3505 	}
   3506 	else
   3507 	{
   3508 		const glw::GLuint alignment = type_size * ((3 == column_length) ? 4 : column_length);
   3509 
   3510 		return alignment * uniform_type.m_n_columns;
   3511 	}
   3512 }
   3513 
   3514 /** Get size used for each member of a uniform array of a given type in a std140 column-major layout
   3515  *
   3516  * @param uniform_type Tested uniform type
   3517  *
   3518  * @return Size of a single member
   3519  **/
   3520 glw::GLuint GPUShaderFP64Test2::getUniformTypeMemberSize(const uniformTypeDetails& uniform_type) const
   3521 {
   3522 	static const glw::GLuint vec4_size	 = 4 * Utils::getBaseVariableTypeComponentSize(Utils::VARIABLE_TYPE_FLOAT);
   3523 	const glw::GLuint		 column_length = uniform_type.m_n_rows;
   3524 
   3525 	/** Size for a layout(std140, column_major) uniform_type uniform[] **/
   3526 	return vec4_size * ((column_length + 1) / 2) * uniform_type.m_n_columns;
   3527 }
   3528 
   3529 /** Get the maximum amount of uniforms to be used in a shader stage for a given type
   3530  *
   3531  * @param shader_stage Tested shader stage id
   3532  * @param uniform_type Tested uniform type
   3533  *
   3534  * @return Number of components
   3535  **/
   3536 glw::GLuint GPUShaderFP64Test2::getAmountUniforms(shaderStage				shader_stage,
   3537 												  const uniformTypeDetails& uniform_type) const
   3538 {
   3539 	const glw::GLuint max_uniform_components   = getMaxUniformComponents(shader_stage);
   3540 	const glw::GLuint required_components	  = getRequiredComponentsNumber(uniform_type);
   3541 	const glw::GLuint n_uniforms			   = max_uniform_components / required_components;
   3542 	const glw::GLuint max_uniform_block_size   = getMaxUniformBlockSize();
   3543 	const glw::GLuint uniform_type_member_size = getUniformTypeMemberSize(uniform_type);
   3544 	const glw::GLuint max_uniforms			   = max_uniform_block_size / uniform_type_member_size;
   3545 
   3546 	return max_uniforms < n_uniforms ? max_uniforms : n_uniforms;
   3547 }
   3548 
   3549 /** Get name of shader stage
   3550  *
   3551  * @param shader_stage Tested shader stage id
   3552  *
   3553  * @return Name
   3554  **/
   3555 const glw::GLchar* GPUShaderFP64Test2::getShaderStageName(shaderStage shader_stage) const
   3556 {
   3557 	switch (shader_stage)
   3558 	{
   3559 	case COMPUTE_SHADER:
   3560 		return "compute shader";
   3561 		break;
   3562 	case FRAGMENT_SHADER:
   3563 		return "fragment shader";
   3564 		break;
   3565 	case GEOMETRY_SHADER:
   3566 		return "geometry shader";
   3567 		break;
   3568 	case TESS_CTRL_SHADER:
   3569 		return "tesselation control shader";
   3570 		break;
   3571 	case TESS_EVAL_SHADER:
   3572 		return "tesselation evaluation shader";
   3573 		break;
   3574 	case VERTEX_SHADER:
   3575 		return "vertex shader";
   3576 		break;
   3577 	}
   3578 
   3579 	return 0;
   3580 }
   3581 
   3582 /** Inspect program to get: buffer_size, offset, strides and block index
   3583  *
   3584  * @param program_id          Program id
   3585  * @param out_buffer_size     Size of uniform buffer
   3586  * @param out_uniform_details Uniform offset and strides
   3587  * @param uniform_block_index Uniform block index
   3588  **/
   3589 void GPUShaderFP64Test2::inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms,
   3590 										const uniformTypeDetails& uniform_type, glw::GLint& out_buffer_size,
   3591 										uniformDetails& out_uniform_details, glw::GLuint uniform_block_index) const
   3592 {
   3593 	glw::GLint				 array_stride = 0;
   3594 	std::vector<glw::GLchar> extracted_uniform_name;
   3595 	const glw::Functions&	gl			   = m_context.getRenderContext().getFunctions();
   3596 	glw::GLuint				 index		   = 0;
   3597 	glw::GLint				 matrix_stride = 0;
   3598 	glw::GLint				 offset		   = 0;
   3599 	glw::GLsizei			 size		   = 0;
   3600 	glw::GLenum				 type		   = 0;
   3601 	const glw::GLchar*		 uniform_name  = 0;
   3602 	std::string				 uniform_name_str;
   3603 	std::stringstream		 uniform_name_stream;
   3604 
   3605 	/* Get index of uniform block */
   3606 	uniform_block_index = gl.getUniformBlockIndex(program_id, m_uniform_block_name);
   3607 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex");
   3608 
   3609 	if (GL_INVALID_INDEX == uniform_block_index)
   3610 	{
   3611 		TCU_FAIL("Unifom block is inactive");
   3612 	}
   3613 
   3614 	/* Get size of uniform block */
   3615 	gl.getActiveUniformBlockiv(program_id, uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &out_buffer_size);
   3616 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv");
   3617 
   3618 	if (0 == out_buffer_size)
   3619 	{
   3620 		TCU_FAIL("Unifom block size is 0");
   3621 	}
   3622 
   3623 	/* Prepare uniform name */
   3624 	uniform_name_stream << "uniform_array";
   3625 
   3626 	uniform_name_str = uniform_name_stream.str();
   3627 	uniform_name	 = uniform_name_str.c_str();
   3628 
   3629 	/* Get index of uniform */
   3630 	gl.getUniformIndices(program_id, 1 /* count */, &uniform_name, &index);
   3631 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
   3632 
   3633 	if (GL_INVALID_INDEX == index)
   3634 	{
   3635 		TCU_FAIL("Unifom is inactive");
   3636 	}
   3637 
   3638 	/* Verify getActiveUniform results */
   3639 	extracted_uniform_name.resize(uniform_name_str.length() * 2);
   3640 
   3641 	gl.getActiveUniform(program_id, index, (glw::GLsizei)(uniform_name_str.length() * 2) /* bufSize */, 0, &size, &type,
   3642 						&extracted_uniform_name[0]);
   3643 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniform");
   3644 
   3645 	if ((n_uniforms != size) || (uniform_type.m_type != type))
   3646 	{
   3647 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid GetActiveUniform results."
   3648 											<< " Size: " << size << " expected: " << n_uniforms << ". Type: " << type
   3649 											<< " expected: " << uniform_type.m_type
   3650 											<< ". Name: " << &extracted_uniform_name[0] << tcu::TestLog::EndMessage;
   3651 
   3652 		TCU_FAIL("Invalid GetActiveUniform results");
   3653 	}
   3654 
   3655 	/* Get offset of uniform */
   3656 	gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset);
   3657 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
   3658 
   3659 	if (-1 == offset)
   3660 	{
   3661 		TCU_FAIL("Unifom has invalid offset");
   3662 	}
   3663 
   3664 	out_uniform_details.m_offset = offset;
   3665 
   3666 	/* Get matrix stride of uniform */
   3667 	gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
   3668 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
   3669 
   3670 	if (-1 == matrix_stride)
   3671 	{
   3672 		TCU_FAIL("Unifom has invalid matrix stride");
   3673 	}
   3674 
   3675 	out_uniform_details.m_matrix_stride = matrix_stride;
   3676 
   3677 	/* Get array stride of uniform */
   3678 	gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_ARRAY_STRIDE, &array_stride);
   3679 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
   3680 
   3681 	if (-1 == matrix_stride)
   3682 	{
   3683 		TCU_FAIL("Unifom has invalid matrix stride");
   3684 	}
   3685 
   3686 	out_uniform_details.m_array_stride = array_stride;
   3687 }
   3688 
   3689 /** Prepare source code for "boilerplate" shaders
   3690  *
   3691  * @param stage_specific_layout    String that will replace STAGE_SPECIFIC_LAYOUT token
   3692  * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token
   3693  * @param out_source_code          Source code
   3694  **/
   3695 void GPUShaderFP64Test2::prepareBoilerplateShader(const glw::GLchar* stage_specific_layout,
   3696 												  const glw::GLchar* stage_specific_main_body,
   3697 												  std::string&		 out_source_code) const
   3698 {
   3699 	/* Shader template */
   3700 	static const glw::GLchar* boilerplate_shader_template_code = "#version 400 core\n"
   3701 																 "\n"
   3702 																 "precision highp float;\n"
   3703 																 "\n"
   3704 																 "STAGE_SPECIFIC_LAYOUT"
   3705 																 "void main()\n"
   3706 																 "{\n"
   3707 																 "STAGE_SPECIFIC_MAIN_BODY"
   3708 																 "}\n"
   3709 																 "\n";
   3710 
   3711 	std::string string = boilerplate_shader_template_code;
   3712 
   3713 	/* Tokens */
   3714 	static const glw::GLchar* body_token   = "STAGE_SPECIFIC_MAIN_BODY";
   3715 	static const glw::GLchar* layout_token = "STAGE_SPECIFIC_LAYOUT";
   3716 
   3717 	size_t search_position = 0;
   3718 
   3719 	/* Replace tokens */
   3720 	Utils::replaceToken(layout_token, search_position, stage_specific_layout, string);
   3721 	Utils::replaceToken(body_token, search_position, stage_specific_main_body, string);
   3722 
   3723 	/* Store resuls */
   3724 	out_source_code = string;
   3725 }
   3726 
   3727 /** Prepare program for given combination of shader stage and uniform type
   3728  *
   3729  * @param shader_stage     Shader stage
   3730  * @param uniform_type     Uniform type
   3731  * @param out_program_info Instance of programInfo
   3732  **/
   3733 void GPUShaderFP64Test2::prepareProgram(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
   3734 										Utils::programInfo& out_program_info) const
   3735 {
   3736 	/* Stage specific layouts */
   3737 	static const glw::GLchar* geometry_shader_layout_code = "layout(points)                   in;\n"
   3738 															"layout(points, max_vertices = 1) out;\n"
   3739 															"\n";
   3740 
   3741 	static const glw::GLchar* tess_ctrl_shader_layout_code = "layout(vertices = 1) out;\n"
   3742 															 "\n";
   3743 
   3744 	static const glw::GLchar* tess_eval_shader_layout_code = "layout(isolines, point_mode) in;\n"
   3745 															 "\n";
   3746 
   3747 	/* Stage specific main body */
   3748 	static const glw::GLchar* boilerplate_fragment_shader_body_code = "    discard;\n";
   3749 
   3750 	static const glw::GLchar* boilerplate_tess_ctrl_shader_body_code = "    gl_TessLevelOuter[0] = 1.0;\n"
   3751 																	   "    gl_TessLevelOuter[1] = 1.0;\n"
   3752 																	   "    gl_TessLevelOuter[2] = 1.0;\n"
   3753 																	   "    gl_TessLevelOuter[3] = 1.0;\n"
   3754 																	   "    gl_TessLevelInner[0] = 1.0;\n"
   3755 																	   "    gl_TessLevelInner[1] = 1.0;\n";
   3756 
   3757 	static const glw::GLchar* boilerplate_vertex_shader_body_code = "    gl_Position = vec4(1, 0, 0, 1);\n";
   3758 
   3759 	static const glw::GLchar* corner_vertex_shader_body_code = "    if (0 == gl_VertexID)\n"
   3760 															   "    {\n"
   3761 															   "        gl_Position = vec4(-1, -1, 0, 1);\n"
   3762 															   "    }\n"
   3763 															   "    else if (1 == gl_VertexID)\n"
   3764 															   "    {\n"
   3765 															   "        gl_Position = vec4(-1, 1, 0, 1);\n"
   3766 															   "    }\n"
   3767 															   "    else if (2 == gl_VertexID)\n"
   3768 															   "    {\n"
   3769 															   "        gl_Position = vec4(1, 1, 0, 1);\n"
   3770 															   "    }\n"
   3771 															   "    else if (3 == gl_VertexID)\n"
   3772 															   "    {\n"
   3773 															   "        gl_Position = vec4(1, -1, 0, 1);\n"
   3774 															   "    }\n";
   3775 
   3776 	static const glw::GLchar* passthrough_tess_eval_shader_body_code = "    result = tcs_tes_result[0];\n";
   3777 
   3778 	static const glw::GLchar* test_shader_body_code = "\n    result = verification_result;\n";
   3779 
   3780 	static const glw::GLchar* test_geometry_shader_body_code = "\n    result = verification_result;\n"
   3781 															   "\n"
   3782 															   "    EmitVertex();\n"
   3783 															   "    EndPrimitive();\n";
   3784 
   3785 	static const glw::GLchar* test_tess_ctrl_shader_body_code =
   3786 		"\n    tcs_tes_result[gl_InvocationID] = verification_result;\n"
   3787 		"\n"
   3788 		"    gl_TessLevelOuter[0] = 1.0;\n"
   3789 		"    gl_TessLevelOuter[1] = 1.0;\n"
   3790 		"    gl_TessLevelOuter[2] = 1.0;\n"
   3791 		"    gl_TessLevelOuter[3] = 1.0;\n"
   3792 		"    gl_TessLevelInner[0] = 1.0;\n"
   3793 		"    gl_TessLevelInner[1] = 1.0;\n";
   3794 
   3795 	/* In variables */
   3796 	static const glw::GLchar* test_tess_ctrl_shader_in_variable = "in  int tcs_tes_result[];\n";
   3797 
   3798 	/* Out variables */
   3799 	static const glw::GLchar* test_fragment_shader_out_variable = "layout(location = 0) out int result;\n";
   3800 
   3801 	static const glw::GLchar* test_tess_ctrl_shader_out_variable = "out int tcs_tes_result[];\n";
   3802 
   3803 	static const glw::GLchar* test_shader_out_variable = "out int result;\n";
   3804 
   3805 	/* Varying name */
   3806 	static const glw::GLchar* varying_name = "result";
   3807 	glw::GLuint				  n_varyings   = 1;
   3808 
   3809 	/* Storage for ready shaders */
   3810 	std::string compute_shader_code;
   3811 	std::string fragment_shader_code;
   3812 	std::string geometry_shader_code;
   3813 	std::string tess_ctrl_shader_code;
   3814 	std::string tess_eval_shader_code;
   3815 	std::string vertex_shader_code;
   3816 
   3817 	/* Storage for uniform definition and verification code */
   3818 	std::string uniform_definitions;
   3819 	std::string uniform_verification;
   3820 
   3821 	/* Get uniform definition and verification code */
   3822 	prepareUniformDefinitions(shader_stage, uniform_type, uniform_definitions);
   3823 	prepareUniformVerification(shader_stage, uniform_type, uniform_verification);
   3824 
   3825 	/* Prepare vertex shader */
   3826 	switch (shader_stage)
   3827 	{
   3828 	case FRAGMENT_SHADER:
   3829 
   3830 		prepareBoilerplateShader("", corner_vertex_shader_body_code, vertex_shader_code);
   3831 
   3832 		break;
   3833 
   3834 	case GEOMETRY_SHADER:
   3835 	case TESS_CTRL_SHADER:
   3836 	case TESS_EVAL_SHADER:
   3837 
   3838 		prepareBoilerplateShader("", boilerplate_vertex_shader_body_code, vertex_shader_code);
   3839 
   3840 		break;
   3841 
   3842 	case VERTEX_SHADER:
   3843 
   3844 		prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */,
   3845 						  test_shader_out_variable /* out var */, uniform_verification.c_str() /* verification */,
   3846 						  test_shader_body_code /* body */, vertex_shader_code);
   3847 
   3848 		break;
   3849 
   3850 	default:
   3851 		break;
   3852 	}
   3853 
   3854 	/* Prepare fragment shader */
   3855 	switch (shader_stage)
   3856 	{
   3857 	case FRAGMENT_SHADER:
   3858 
   3859 		prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */,
   3860 						  test_fragment_shader_out_variable /* out var */,
   3861 						  uniform_verification.c_str() /* verification */, test_shader_body_code /* body */,
   3862 						  fragment_shader_code);
   3863 
   3864 		break;
   3865 
   3866 	case GEOMETRY_SHADER:
   3867 	case TESS_CTRL_SHADER:
   3868 	case TESS_EVAL_SHADER:
   3869 	case VERTEX_SHADER:
   3870 
   3871 		prepareBoilerplateShader("" /* layout */, boilerplate_fragment_shader_body_code /* body */,
   3872 								 fragment_shader_code);
   3873 
   3874 		break;
   3875 
   3876 	default:
   3877 		break;
   3878 	}
   3879 
   3880 	/* Prepare compute, tess_ctrl, tess_eval, geometry shaders */
   3881 	switch (shader_stage)
   3882 	{
   3883 	case COMPUTE_SHADER:
   3884 
   3885 		prepareTestComputeShader(uniform_definitions.c_str(), uniform_verification.c_str(), compute_shader_code);
   3886 
   3887 		break;
   3888 
   3889 	case GEOMETRY_SHADER:
   3890 
   3891 		prepareTestShader(geometry_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
   3892 						  "" /* in var */, test_shader_out_variable /* out var */,
   3893 						  uniform_verification.c_str() /* verification */, test_geometry_shader_body_code /* body */,
   3894 						  geometry_shader_code);
   3895 
   3896 		break;
   3897 
   3898 	case TESS_CTRL_SHADER:
   3899 
   3900 		prepareTestShader(tess_ctrl_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
   3901 						  "" /* in var */, test_tess_ctrl_shader_out_variable /* out var */,
   3902 						  uniform_verification.c_str() /* verification */, test_tess_ctrl_shader_body_code /* body */,
   3903 						  tess_ctrl_shader_code);
   3904 
   3905 		prepareTestShader(tess_eval_shader_layout_code /* layout */, "" /* uniforms */,
   3906 						  test_tess_ctrl_shader_in_variable /* in var */, test_shader_out_variable /* out var */,
   3907 						  "" /* verification */, passthrough_tess_eval_shader_body_code /* body */,
   3908 						  tess_eval_shader_code);
   3909 
   3910 		break;
   3911 
   3912 	case TESS_EVAL_SHADER:
   3913 
   3914 		prepareBoilerplateShader(tess_ctrl_shader_layout_code /* layout */,
   3915 								 boilerplate_tess_ctrl_shader_body_code /* body */, tess_ctrl_shader_code);
   3916 
   3917 		prepareTestShader(tess_eval_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
   3918 						  "" /* in var */, test_shader_out_variable /* out var */,
   3919 						  uniform_verification.c_str() /* verification */, test_shader_body_code /* body */,
   3920 						  tess_eval_shader_code);
   3921 
   3922 		break;
   3923 
   3924 	default:
   3925 		break;
   3926 	};
   3927 
   3928 	/* Select shaders that will be used by program */
   3929 	const glw::GLchar* cs_c_str  = 0;
   3930 	const glw::GLchar* fs_c_str  = 0;
   3931 	const glw::GLchar* gs_c_str  = 0;
   3932 	const glw::GLchar* tcs_c_str = 0;
   3933 	const glw::GLchar* tes_c_str = 0;
   3934 	const glw::GLchar* vs_c_str  = 0;
   3935 
   3936 	if (false == compute_shader_code.empty())
   3937 	{
   3938 		cs_c_str = compute_shader_code.c_str();
   3939 	}
   3940 
   3941 	if (false == fragment_shader_code.empty())
   3942 	{
   3943 		fs_c_str = fragment_shader_code.c_str();
   3944 	}
   3945 
   3946 	if (false == geometry_shader_code.empty())
   3947 	{
   3948 		gs_c_str = geometry_shader_code.c_str();
   3949 	}
   3950 
   3951 	if (false == tess_ctrl_shader_code.empty())
   3952 	{
   3953 		tcs_c_str = tess_ctrl_shader_code.c_str();
   3954 	}
   3955 
   3956 	if (false == tess_eval_shader_code.empty())
   3957 	{
   3958 		tes_c_str = tess_eval_shader_code.c_str();
   3959 	}
   3960 
   3961 	if (false == vertex_shader_code.empty())
   3962 	{
   3963 		vs_c_str = vertex_shader_code.c_str();
   3964 	}
   3965 
   3966 	/* Compute and fragment shader results are stored in texture, do not set varyings for transfrom feedback */
   3967 	if ((COMPUTE_SHADER == shader_stage) || (FRAGMENT_SHADER == shader_stage))
   3968 	{
   3969 		n_varyings = 0;
   3970 	}
   3971 
   3972 	/* Build */
   3973 	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);
   3974 }
   3975 
   3976 /** Prepare collection of tested shader stages
   3977  *
   3978  */
   3979 void GPUShaderFP64Test2::prepareShaderStages()
   3980 {
   3981 	/* m_pDispatchCompute is initialized only if compute_shader are supproted and context is at least 4.2 */
   3982 	if (0 != m_pDispatchCompute)
   3983 	{
   3984 		m_shader_stages.push_back(COMPUTE_SHADER);
   3985 	}
   3986 
   3987 	m_shader_stages.push_back(FRAGMENT_SHADER);
   3988 	m_shader_stages.push_back(GEOMETRY_SHADER);
   3989 	m_shader_stages.push_back(TESS_CTRL_SHADER);
   3990 	m_shader_stages.push_back(TESS_EVAL_SHADER);
   3991 	m_shader_stages.push_back(VERTEX_SHADER);
   3992 }
   3993 
   3994 /** Prepare source code for "tested" shader stage
   3995  *
   3996  * @param stage_specific_layout    String that will replace STAGE_SPECIFIC_LAYOUT token
   3997  * @param uniform_definitions      String that will replace UNIFORM_DEFINITIONS token
   3998  * @param in_variable_definitions  String that will replace IN_VARIABLE_DEFINITION token
   3999  * @param out_variable_definitions String that will replace OUT_VARIABLE_DEFINITION token
   4000  * @param uniform_verification     String that will replace UNIFORM_VERIFICATION token
   4001  * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token
   4002  * @param out_source_code          Shader source code
   4003  **/
   4004 void GPUShaderFP64Test2::prepareTestShader(const glw::GLchar* stage_specific_layout,
   4005 										   const glw::GLchar* uniform_definitions,
   4006 										   const glw::GLchar* in_variable_definitions,
   4007 										   const glw::GLchar* out_variable_definitions,
   4008 										   const glw::GLchar* uniform_verification,
   4009 										   const glw::GLchar* stage_specific_main_body,
   4010 										   std::string&		  out_source_code) const
   4011 {
   4012 	/* Shader template */
   4013 	static const glw::GLchar* test_shader_template_code = "#version 400 core\n"
   4014 														  "\n"
   4015 														  "precision highp float;\n"
   4016 														  "\n"
   4017 														  "STAGE_SPECIFIC_LAYOUT"
   4018 														  "UNIFORM_DEFINITIONS"
   4019 														  "IN_VARIABLE_DEFINITION"
   4020 														  "OUT_VARIABLE_DEFINITION"
   4021 														  "\n"
   4022 														  "void main()\n"
   4023 														  "{\n"
   4024 														  "UNIFORM_VERIFICATION"
   4025 														  "STAGE_SPECIFIC_MAIN_BODY"
   4026 														  "}\n"
   4027 														  "\n";
   4028 
   4029 	std::string string = test_shader_template_code;
   4030 
   4031 	/* Tokens */
   4032 	static const glw::GLchar* body_token	= "STAGE_SPECIFIC_MAIN_BODY";
   4033 	static const glw::GLchar* in_var_token  = "IN_VARIABLE_DEFINITION";
   4034 	static const glw::GLchar* layout_token  = "STAGE_SPECIFIC_LAYOUT";
   4035 	static const glw::GLchar* out_var_token = "OUT_VARIABLE_DEFINITION";
   4036 	static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS";
   4037 	static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION";
   4038 
   4039 	size_t search_position = 0;
   4040 
   4041 	/* Replace tokens */
   4042 	Utils::replaceToken(layout_token, search_position, stage_specific_layout, string);
   4043 	Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string);
   4044 	Utils::replaceToken(in_var_token, search_position, in_variable_definitions, string);
   4045 	Utils::replaceToken(out_var_token, search_position, out_variable_definitions, string);
   4046 	Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string);
   4047 	Utils::replaceToken(body_token, search_position, stage_specific_main_body, string);
   4048 
   4049 	/* Store resuls */
   4050 	out_source_code = string;
   4051 }
   4052 
   4053 /** Prepare source code for "tested" compute shaders
   4054  *
   4055  * @param uniform_definitions  String that will replace UNIFORM_DEFINITIONS token
   4056  * @param uniform_verification String that will replace UNIFORM_VERIFICATION token
   4057  * @param out_source_code      Source code
   4058  **/
   4059 void GPUShaderFP64Test2::prepareTestComputeShader(const glw::GLchar* uniform_definitions,
   4060 												  const glw::GLchar* uniform_verification,
   4061 												  std::string&		 out_source_code) const
   4062 {
   4063 	/* Shader template */
   4064 	static const glw::GLchar* test_shader_template_code =
   4065 		"#version 420 core\n"
   4066 		"#extension GL_ARB_compute_shader          : require\n"
   4067 		"#extension GL_ARB_shader_image_load_store : require\n"
   4068 		"\n"
   4069 		"precision highp float;\n"
   4070 		"\n"
   4071 		"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
   4072 		"\n"
   4073 		"UNIFORM_DEFINITIONS"
   4074 		"layout(r32i) writeonly uniform iimage2D result;\n"
   4075 		"\n"
   4076 		"void main()\n"
   4077 		"{\n"
   4078 		"UNIFORM_VERIFICATION"
   4079 		"\n"
   4080 		"    imageStore(result, ivec2(gl_WorkGroupID.xy), ivec4(verification_result, 0, 0, 0));\n"
   4081 		"}\n"
   4082 		"\n";
   4083 
   4084 	std::string string = test_shader_template_code;
   4085 
   4086 	/* Tokens */
   4087 	static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS";
   4088 	static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION";
   4089 
   4090 	size_t search_position = 0;
   4091 
   4092 	/* Replace tokens */
   4093 	Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string);
   4094 	Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string);
   4095 
   4096 	/* Store resuls */
   4097 	out_source_code = string;
   4098 }
   4099 
   4100 /** Prepare source code which defines uniforms for tested shader stage
   4101  *
   4102  * @param shader_stage    Shader stage id
   4103  * @param uniform_type    Details of uniform type
   4104  * @param out_source_code Source code
   4105  **/
   4106 void GPUShaderFP64Test2::prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
   4107 												   std::string& out_source_code) const
   4108 {
   4109 	const glw::GLuint n_uniforms = getAmountUniforms(shader_stage, uniform_type);
   4110 	std::stringstream stream;
   4111 
   4112 	/*
   4113 	 * layout(std140) uniform M_UNIFORM_BLOCK_NAME
   4114 	 * {
   4115 	 *     TYPE_NAME uniform_array[N_UNIFORMS];
   4116 	 * };
   4117 	 */
   4118 	stream << "layout(std140) uniform " << m_uniform_block_name << "\n"
   4119 																   "{\n";
   4120 
   4121 	stream << "    " << uniform_type.m_type_name << " uniform_array[" << n_uniforms << "];\n";
   4122 
   4123 	stream << "};\n\n";
   4124 
   4125 	out_source_code = stream.str();
   4126 }
   4127 
   4128 /** Prepare uniform buffer for test
   4129  *
   4130  * @param shader_stage Shader stage id
   4131  * @param uniform_type Details of uniform type
   4132  * @param program_info Program object info
   4133  **/
   4134 void GPUShaderFP64Test2::prepareUniforms(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
   4135 										 const Utils::programInfo& program_info) const
   4136 {
   4137 	glw::GLint				  buffer_size	 = 0;
   4138 	glw::GLuint				  element_ordinal = 1;
   4139 	const glw::Functions&	 gl			  = m_context.getRenderContext().getFunctions();
   4140 	const glw::GLuint		  n_columns		  = uniform_type.m_n_columns;
   4141 	const glw::GLuint		  n_rows		  = uniform_type.m_n_rows;
   4142 	const glw::GLuint		  n_elements	  = n_columns * n_rows;
   4143 	uniformDetails			  uniform_details;
   4144 	const glw::GLuint		  program_id = program_info.m_program_object_id;
   4145 	const glw::GLint		  n_uniforms = getAmountUniforms(shader_stage, uniform_type);
   4146 	std::vector<glw::GLubyte> uniform_buffer_data;
   4147 	glw::GLuint				  uniform_block_index = 0;
   4148 
   4149 	/* Get uniform details */
   4150 	inspectProgram(program_id, n_uniforms, uniform_type, buffer_size, uniform_details, uniform_block_index);
   4151 
   4152 	/* Uniform offset and strides */
   4153 	const glw::GLuint array_stride   = uniform_details.m_array_stride;
   4154 	const glw::GLuint matrix_stride  = uniform_details.m_matrix_stride;
   4155 	const glw::GLuint uniform_offset = uniform_details.m_offset;
   4156 
   4157 	/* Prepare storage for buffer data */
   4158 	uniform_buffer_data.resize(buffer_size);
   4159 
   4160 	/* Prepare uniform data */
   4161 	for (glw::GLint i = 0; i < n_uniforms; ++i)
   4162 	{
   4163 		const glw::GLuint array_entry_offset = uniform_offset + i * array_stride;
   4164 
   4165 		for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal)
   4166 		{
   4167 			const glw::GLuint   column		 = element / n_rows;
   4168 			const glw::GLuint   column_elem  = element % n_rows;
   4169 			const glw::GLdouble value		 = element_ordinal;
   4170 			const glw::GLuint   value_offset = static_cast<glw::GLuint>(array_entry_offset + column * matrix_stride +
   4171 																	  column_elem * sizeof(glw::GLdouble));
   4172 			glw::GLdouble* value_dst = (glw::GLdouble*)&uniform_buffer_data[value_offset];
   4173 
   4174 			*value_dst = value;
   4175 		}
   4176 	}
   4177 
   4178 	/* Update uniform buffer with new set of data */
   4179 	gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id);
   4180 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
   4181 
   4182 	gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &uniform_buffer_data[0], GL_STATIC_DRAW);
   4183 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
   4184 
   4185 	/* Bind uniform block to uniform buffer */
   4186 	gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0 /* offset */, buffer_size);
   4187 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
   4188 
   4189 	gl.uniformBlockBinding(program_id, uniform_block_index, 0 /* binding */);
   4190 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding");
   4191 }
   4192 
   4193 /** Prepare collection of tested uniform types
   4194  *
   4195  **/
   4196 void GPUShaderFP64Test2::prepareUniformTypes()
   4197 {
   4198 	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 1 /* n_rows */));
   4199 	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 2 /* n_rows */));
   4200 	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 3 /* n_rows */));
   4201 	m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 4 /* n_rows */));
   4202 	m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 2 /* n_rows */));
   4203 	m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 3 /* n_rows */));
   4204 	m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 4 /* n_rows */));
   4205 	m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 2 /* n_rows */));
   4206 	m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 3 /* n_rows */));
   4207 	m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 4 /* n_rows */));
   4208 	m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 2 /* n_rows */));
   4209 	m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 3 /* n_rows */));
   4210 	m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 4 /* n_rows */));
   4211 }
   4212 
   4213 /** Prepare source code that verifes uniform values
   4214  *
   4215  * @param shader_stage    Shader stage id
   4216  * @param uniform_type    Details of uniform type
   4217  * @param out_source_code Source code
   4218  **/
   4219 void GPUShaderFP64Test2::prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
   4220 													std::string& out_source_code) const
   4221 {
   4222 	glw::GLuint		  element_ordinal = 1;
   4223 	const glw::GLuint n_columns		  = uniform_type.m_n_columns;
   4224 	const glw::GLuint n_rows		  = uniform_type.m_n_rows;
   4225 	const glw::GLuint n_elements	  = n_columns * n_rows;
   4226 	const glw::GLuint n_uniforms	  = getAmountUniforms(shader_stage, uniform_type);
   4227 	std::stringstream stream;
   4228 
   4229 	/*
   4230 	 * int verification_result = M_RESULT_SUCCESS;
   4231 	 *
   4232 	 * for (int i = 0; i < N_UNIFORMS; ++i)
   4233 	 * {
   4234 	 *     if (TYPE_NAME(i * (N_ELEMENTS) + 1) != uniform_array[i])
   4235 	 *     {
   4236 	 *         verification_result = M_RESULT_FAILURE
   4237 	 *     }
   4238 	 * }
   4239 	 */
   4240 	stream << "    int verification_result = " << m_result_success << ";\n"
   4241 																	  "\n"
   4242 																	  "    for (int i = 0; i < "
   4243 		   << n_uniforms << "; ++i)\n"
   4244 							"    {\n"
   4245 							"        if ("
   4246 		   << uniform_type.m_type_name << "(";
   4247 
   4248 	for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal)
   4249 	{
   4250 		stream << "i * (" << n_elements << ") + " << element + 1;
   4251 
   4252 		if (n_elements != element + 1)
   4253 		{
   4254 			stream << ", ";
   4255 		}
   4256 	}
   4257 
   4258 	stream << ") != uniform_array[i])\n"
   4259 			  "        {\n"
   4260 			  "           verification_result = "
   4261 		   << m_result_failure << ";\n"
   4262 								  "        }\n"
   4263 								  "    }\n";
   4264 
   4265 	out_source_code = stream.str();
   4266 }
   4267 
   4268 /** Execute test for given combination of "tested" shader stage and uniform type
   4269  *
   4270  * @param shader_stage Tested shader stage id
   4271  * @param uniform_type Tested uniform type
   4272  *
   4273  * @return true if test passed, false otherwise
   4274  **/
   4275 bool GPUShaderFP64Test2::test(shaderStage shader_stage, const uniformTypeDetails& uniform_type) const
   4276 {
   4277 	const glw::GLenum		draw_primitive = getDrawPrimitiveType(shader_stage);
   4278 	static const glw::GLint first_vertex   = 0;
   4279 	const glw::Functions&   gl			   = m_context.getRenderContext().getFunctions();
   4280 	const glw::GLsizei		n_vertices	 = (FRAGMENT_SHADER == shader_stage) ? 4 : m_n_captured_results;
   4281 	Utils::programInfo		program_info(m_context);
   4282 	bool					result = true;
   4283 
   4284 	/* Prepare program */
   4285 	prepareProgram(shader_stage, uniform_type, program_info);
   4286 
   4287 	gl.useProgram(program_info.m_program_object_id);
   4288 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   4289 
   4290 	/* Prepare uniform buffer and bind it with uniform block */
   4291 	prepareUniforms(shader_stage, uniform_type, program_info);
   4292 
   4293 	/* Prepare storage for test results */
   4294 	testBegin(program_info.m_program_object_id, shader_stage);
   4295 
   4296 	/* Execute */
   4297 	if (COMPUTE_SHADER == shader_stage)
   4298 	{
   4299 		m_pDispatchCompute(m_texture_width, m_texture_height, 1);
   4300 		GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
   4301 	}
   4302 	else
   4303 	{
   4304 		gl.drawArrays(draw_primitive, first_vertex, n_vertices);
   4305 		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   4306 	}
   4307 
   4308 	/* Clean after test */
   4309 	testEnd(shader_stage);
   4310 
   4311 	/* Check results */
   4312 	if (false == verifyResults(shader_stage))
   4313 	{
   4314 		m_context.getTestContext().getLog()
   4315 			<< tcu::TestLog::Message << "Shader stage: " << getShaderStageName(shader_stage)
   4316 			<< ". Uniform type: " << uniform_type.m_type_name << tcu::TestLog::EndMessage;
   4317 
   4318 		result = false;
   4319 	}
   4320 
   4321 	return result;
   4322 }
   4323 
   4324 /** Prepare transform feedback buffer, framebuffer or image unit for test results
   4325  *
   4326  * @param program_id   Program object id
   4327  * @param shader_stage Tested shader stage id
   4328  **/
   4329 void GPUShaderFP64Test2::testBegin(glw::GLuint program_id, shaderStage shader_stage) const
   4330 {
   4331 	std::vector<glw::GLint> buffer_data;
   4332 	const glw::GLenum		captured_primitive = getCapturedPrimitiveType(shader_stage);
   4333 	const glw::Functions&   gl				   = m_context.getRenderContext().getFunctions();
   4334 
   4335 	/* Prepare buffer filled with m_result_failure */
   4336 	buffer_data.resize(m_n_captured_results);
   4337 	for (glw::GLuint i = 0; i < m_n_captured_results; ++i)
   4338 	{
   4339 		buffer_data[i] = m_result_failure;
   4340 	}
   4341 
   4342 	/* Prepare buffer for test results */
   4343 	switch (shader_stage)
   4344 	{
   4345 	case GEOMETRY_SHADER:
   4346 	case TESS_CTRL_SHADER:
   4347 	case TESS_EVAL_SHADER:
   4348 	case VERTEX_SHADER:
   4349 
   4350 		/* Verify getTransformFeedbackVarying results */
   4351 		{
   4352 			glw::GLsizei size = 0;
   4353 			glw::GLenum  type = 0;
   4354 			glw::GLchar  name[16];
   4355 
   4356 			gl.getTransformFeedbackVarying(program_id, 0 /* index */, 16 /* bufSize */, 0 /* length */, &size, &type,
   4357 										   name);
   4358 			GLU_EXPECT_NO_ERROR(gl.getError(), "GetTransformFeedbackVarying");
   4359 
   4360 			if ((1 != size) || (GL_INT != type) || (0 != strcmp("result", name)))
   4361 			{
   4362 				m_context.getTestContext().getLog()
   4363 					<< tcu::TestLog::Message << "Error. Invalid GetTransformFeedbackVarying results."
   4364 					<< " Size: " << size << " expected: " << 1 << ". Type: " << type << " expected: " << GL_INT
   4365 					<< ". Name: " << name << " expected: result" << tcu::TestLog::EndMessage;
   4366 
   4367 				TCU_FAIL("Invalid GetTransformFeedbackVarying results");
   4368 			}
   4369 		}
   4370 
   4371 		/* Create/clean transform feedback buffer */
   4372 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
   4373 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
   4374 
   4375 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_size, &buffer_data[0], GL_DYNAMIC_COPY);
   4376 		GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
   4377 
   4378 		/* Set up transform feedback buffer */
   4379 		gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */,
   4380 						   m_transform_feedback_buffer_size);
   4381 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
   4382 
   4383 		gl.beginTransformFeedback(captured_primitive);
   4384 		GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   4385 
   4386 		break;
   4387 
   4388 	case FRAGMENT_SHADER:
   4389 
   4390 		/* Clean texture */
   4391 		gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
   4392 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   4393 
   4394 		gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height,
   4395 						 GL_RED_INTEGER, GL_INT, &buffer_data[0]);
   4396 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
   4397 
   4398 		/* Set up texture as color attachment 0 */
   4399 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
   4400 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
   4401 
   4402 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /* level */);
   4403 		GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
   4404 
   4405 		gl.viewport(0 /* x */, 0 /* y */, m_texture_width, m_texture_height);
   4406 		GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
   4407 
   4408 		break;
   4409 
   4410 	case COMPUTE_SHADER:
   4411 
   4412 		/* Clean texture */
   4413 		gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
   4414 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   4415 
   4416 		gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height,
   4417 						 GL_RED_INTEGER, GL_INT, &buffer_data[0]);
   4418 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
   4419 
   4420 		glw::GLint location = gl.getUniformLocation(program_id, "result");
   4421 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
   4422 
   4423 		if (-1 == location)
   4424 		{
   4425 			TCU_FAIL("Inactive uniform \"result\"");
   4426 		}
   4427 
   4428 		gl.uniform1i(location, 0 /* first image unit */);
   4429 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
   4430 
   4431 		/* Bind texture to first image unit */
   4432 		gl.bindImageTexture(0 /* first image unit */, m_texture_id, 0 /* level */, GL_FALSE /* layered */,
   4433 							0 /* layer */, GL_WRITE_ONLY, GL_R32I);
   4434 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
   4435 
   4436 		break;
   4437 	}
   4438 }
   4439 
   4440 /** Unbind transform feedback buffer, framebuffer or image unit
   4441  *
   4442  * @param shader_stage Tested shader stage id
   4443  **/
   4444 void GPUShaderFP64Test2::testEnd(shaderStage shader_stage) const
   4445 {
   4446 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4447 
   4448 	switch (shader_stage)
   4449 	{
   4450 	case GEOMETRY_SHADER:
   4451 	case TESS_CTRL_SHADER:
   4452 	case TESS_EVAL_SHADER:
   4453 	case VERTEX_SHADER:
   4454 
   4455 		gl.endTransformFeedback();
   4456 
   4457 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
   4458 
   4459 		break;
   4460 
   4461 	case FRAGMENT_SHADER:
   4462 
   4463 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture_id */,
   4464 								0 /* level */);
   4465 
   4466 		gl.bindTexture(GL_TEXTURE_2D, 0);
   4467 
   4468 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
   4469 
   4470 		break;
   4471 
   4472 	case COMPUTE_SHADER:
   4473 
   4474 		gl.bindImageTexture(0 /* first image unit */, 0 /* texture_id */, 0 /* level */, GL_FALSE /* layered */,
   4475 							0 /* layer */, GL_WRITE_ONLY, GL_R32I);
   4476 
   4477 		break;
   4478 	}
   4479 }
   4480 
   4481 /** Initialize OpenGL objects for test
   4482  *
   4483  **/
   4484 void GPUShaderFP64Test2::testInit()
   4485 {
   4486 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4487 
   4488 	/* The test is in 4.0 group. However:
   4489 	 * - compute_shader is core since 4.3
   4490 	 * - compute_shader require at least version 4.2 of GL */
   4491 	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
   4492 		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
   4493 	{
   4494 		m_pDispatchCompute = (arbDispatchComputeFunc)gl.dispatchCompute;
   4495 	}
   4496 
   4497 	/* Tesselation patch set up */
   4498 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
   4499 	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
   4500 
   4501 	/* Generate FBO */
   4502 	gl.genFramebuffers(1, &m_framebuffer_id);
   4503 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
   4504 
   4505 	/* Prepare texture */
   4506 	gl.genTextures(1, &m_texture_id);
   4507 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
   4508 
   4509 	gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
   4510 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   4511 
   4512 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, m_texture_width, m_texture_height);
   4513 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
   4514 
   4515 	/* Prepare transform feedback buffer */
   4516 	gl.genBuffers(1, &m_transform_feedback_buffer_id);
   4517 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
   4518 
   4519 	/* Generate uniform buffer */
   4520 	gl.genBuffers(1, &m_uniform_buffer_id);
   4521 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
   4522 
   4523 	/* Prepare VAO */
   4524 	gl.genVertexArrays(1, &m_vertex_array_object_id);
   4525 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
   4526 
   4527 	gl.bindVertexArray(m_vertex_array_object_id);
   4528 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
   4529 }
   4530 
   4531 /** Result verification, expected result is that whole buffer is filled with m_result_success
   4532  *
   4533  * @param shader_stage Tested shader stage id
   4534  **/
   4535 bool GPUShaderFP64Test2::verifyResults(shaderStage shader_stage) const
   4536 {
   4537 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4538 
   4539 	if ((FRAGMENT_SHADER == shader_stage) || (COMPUTE_SHADER == shader_stage))
   4540 	{
   4541 		/* Verify contents of texture */
   4542 
   4543 		/* Prepare storage for testure data */
   4544 		std::vector<glw::GLint> image_data;
   4545 		image_data.resize(m_texture_width * m_texture_height);
   4546 
   4547 		/* Get texture contents */
   4548 		gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
   4549 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   4550 
   4551 		gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]);
   4552 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
   4553 
   4554 		for (glw::GLuint y = 0; y < m_texture_width; ++y)
   4555 		{
   4556 			for (glw::GLuint x = 0; x < m_texture_height; ++x)
   4557 			{
   4558 				const glw::GLuint offset = y * m_texture_width + x;
   4559 				const glw::GLint  value  = image_data[offset];
   4560 
   4561 				if (m_result_success != value)
   4562 				{
   4563 					m_context.getTestContext().getLog()
   4564 						<< tcu::TestLog::Message << "Error. Texture contents are wrong at (" << x << ", " << y << ")"
   4565 						<< tcu::TestLog::EndMessage;
   4566 
   4567 					return false;
   4568 				}
   4569 			}
   4570 		}
   4571 
   4572 		return true;
   4573 	}
   4574 	else
   4575 	{
   4576 		/* Verify contents of transform feedback buffer */
   4577 
   4578 		bool result = true;
   4579 
   4580 		/* Get transform feedback data */
   4581 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
   4582 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
   4583 
   4584 		glw::GLint* feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   4585 		GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   4586 
   4587 		for (glw::GLuint i = 0; i < m_n_captured_results; ++i)
   4588 		{
   4589 			const glw::GLint value = feedback_data[i];
   4590 
   4591 			if (m_result_success != value)
   4592 			{
   4593 				m_context.getTestContext().getLog() << tcu::TestLog::Message
   4594 													<< "Error. Transform feedback buffer contents are wrong at " << i
   4595 													<< tcu::TestLog::EndMessage;
   4596 
   4597 				result = false;
   4598 				break;
   4599 			}
   4600 		}
   4601 
   4602 		/* Unmap transform feedback buffer */
   4603 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   4604 		GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   4605 
   4606 		return result;
   4607 	}
   4608 }
   4609 
   4610 /* Definitions of static const fields declared in GPUShaderFP64Test3 */
   4611 const glw::GLuint GPUShaderFP64Test3::m_result_failure = 0;
   4612 const glw::GLuint GPUShaderFP64Test3::m_result_success = 1;
   4613 
   4614 const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_name			 = "UniformBlock";
   4615 const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_instance_name = "uniform_block";
   4616 
   4617 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_fs_out_fs_result   = "fs_out_fs_result";
   4618 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_gs_result	= "gs_fs_gs_result";
   4619 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tcs_result   = "gs_fs_tcs_result";
   4620 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tes_result   = "gs_fs_tes_result";
   4621 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_vs_result	= "gs_fs_vs_result";
   4622 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_tcs_result = "tcs_tes_tcs_result";
   4623 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_vs_result  = "tcs_tes_vs_result";
   4624 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tcs_result  = "tes_gs_tcs_result";
   4625 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tes_result  = "tes_gs_tes_result";
   4626 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_vs_result   = "tes_gs_vs_result";
   4627 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_vs_tcs_vs_result   = "vs_tcs_vs_result";
   4628 
   4629 /* Definitions of static const fields declared in GPUShaderFP64Test3::programInfo */
   4630 const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_offset			 = -1;
   4631 const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_matrix_stride	= -1;
   4632 const glw::GLint GPUShaderFP64Test3::programInfo::m_non_matrix_uniform_matrix_stride = 0;
   4633 
   4634 /** Constructor
   4635  *
   4636  * @param context Test context
   4637  **/
   4638 GPUShaderFP64Test3::GPUShaderFP64Test3(deqp::Context& context)
   4639 	: TestCase(context, "named_uniform_blocks",
   4640 			   "Verifies usage of \"double precision\" floats in \"named uniform block\"")
   4641 {
   4642 	/* Nothing to be done */
   4643 }
   4644 
   4645 /** Deinitialize test
   4646  *
   4647  **/
   4648 void GPUShaderFP64Test3::deinit()
   4649 {
   4650 	/* GL entry points */
   4651 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4652 
   4653 	/* Clean programs */
   4654 	m_packed_program.deinit(m_context);
   4655 	m_shared_program.deinit(m_context);
   4656 	m_std140_program.deinit(m_context);
   4657 
   4658 	/* Clean frambuffer */
   4659 	if (0 != m_framebuffer_id)
   4660 	{
   4661 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
   4662 		gl.deleteFramebuffers(1, &m_framebuffer_id);
   4663 
   4664 		m_framebuffer_id = 0;
   4665 	}
   4666 
   4667 	/* Clean texture */
   4668 	if (0 != m_color_texture_id)
   4669 	{
   4670 		gl.bindTexture(GL_TEXTURE_2D, 0);
   4671 		gl.deleteTextures(1, &m_color_texture_id);
   4672 
   4673 		m_color_texture_id = 0;
   4674 	}
   4675 
   4676 	/* Clean buffers */
   4677 	if (0 != m_transform_feedback_buffer_id)
   4678 	{
   4679 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
   4680 		gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
   4681 
   4682 		m_transform_feedback_buffer_id = 0;
   4683 	}
   4684 
   4685 	if (0 != m_uniform_buffer_id)
   4686 	{
   4687 		gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
   4688 		gl.deleteBuffers(1, &m_uniform_buffer_id);
   4689 
   4690 		m_uniform_buffer_id = 0;
   4691 	}
   4692 
   4693 	/* Clean VAO */
   4694 	if (0 != m_vertex_array_object_id)
   4695 	{
   4696 		gl.bindVertexArray(0);
   4697 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
   4698 
   4699 		m_vertex_array_object_id = 0;
   4700 	}
   4701 }
   4702 
   4703 /** Execute test
   4704  *
   4705  * @return tcu::TestNode::STOP
   4706  **/
   4707 tcu::TestNode::IterateResult GPUShaderFP64Test3::iterate()
   4708 {
   4709 	bool result = true;
   4710 
   4711 	/* Check if extension is supported */
   4712 	if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
   4713 	{
   4714 		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
   4715 	}
   4716 
   4717 	/* Initialize test */
   4718 	testInit();
   4719 
   4720 	/* Test "packed" uniform buffer layout */
   4721 	if (false == test(PACKED))
   4722 	{
   4723 		result = false;
   4724 	}
   4725 
   4726 	/* Test "shared" uniform buffer layout */
   4727 	if (false == test(SHARED))
   4728 	{
   4729 		result = false;
   4730 	}
   4731 
   4732 	/* Test "std140" uniform buffer layout */
   4733 	if (false == test(STD140))
   4734 	{
   4735 		result = false;
   4736 	}
   4737 
   4738 	/* Set result */
   4739 	if (true == result)
   4740 	{
   4741 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4742 	}
   4743 	else
   4744 	{
   4745 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4746 	}
   4747 
   4748 	/* Done */
   4749 	return tcu::TestNode::STOP;
   4750 }
   4751 
   4752 /** Constructor
   4753  *
   4754  **/
   4755 GPUShaderFP64Test3::programInfo::programInfo()
   4756 	: m_fragment_shader_id(0)
   4757 	, m_geometry_shader_id(0)
   4758 	, m_program_object_id(0)
   4759 	, m_tesselation_control_shader_id(0)
   4760 	, m_tesselation_evaluation_shader_id(0)
   4761 	, m_vertex_shader_id(0)
   4762 	, m_buffer_size(0)
   4763 	, m_uniform_block_index(0)
   4764 {
   4765 	/* Nothing to be done here */
   4766 }
   4767 
   4768 /** Compile shader
   4769  *
   4770  * @param context     Test context
   4771  * @param shader_id   Shader object id
   4772  * @param shader_code Shader source code
   4773  **/
   4774 void GPUShaderFP64Test3::programInfo::compile(deqp::Context& context, glw::GLuint shader_id,
   4775 											  const glw::GLchar* shader_code) const
   4776 {
   4777 	/* GL entry points */
   4778 	const glw::Functions& gl = context.getRenderContext().getFunctions();
   4779 
   4780 	/* Compilation status */
   4781 	glw::GLint status = GL_FALSE;
   4782 
   4783 	/* Set source code */
   4784 	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
   4785 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
   4786 
   4787 	/* Compile */
   4788 	gl.compileShader(shader_id);
   4789 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
   4790 
   4791 	/* Get compilation status */
   4792 	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
   4793 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
   4794 
   4795 	/* Log compilation error */
   4796 	if (GL_TRUE != status)
   4797 	{
   4798 		glw::GLint				 length = 0;
   4799 		std::vector<glw::GLchar> message;
   4800 
   4801 		/* Error log length */
   4802 		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
   4803 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
   4804 
   4805 		/* Prepare storage */
   4806 		message.resize(length);
   4807 
   4808 		/* Get error log */
   4809 		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
   4810 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
   4811 
   4812 		/* Log */
   4813 		context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
   4814 										  << &message[0] << "\nShader source\n"
   4815 										  << shader_code << tcu::TestLog::EndMessage;
   4816 
   4817 		TCU_FAIL("Failed to compile shader");
   4818 	}
   4819 }
   4820 
   4821 /** Cleans program and attached shaders
   4822  *
   4823  * @param context Test context
   4824  **/
   4825 void GPUShaderFP64Test3::programInfo::deinit(deqp::Context& context)
   4826 {
   4827 	/* GL entry points */
   4828 	const glw::Functions& gl = context.getRenderContext().getFunctions();
   4829 
   4830 	/* Restore default program */
   4831 	gl.useProgram(0);
   4832 
   4833 	/* Clean program object */
   4834 	if (0 != m_program_object_id)
   4835 	{
   4836 		gl.deleteProgram(m_program_object_id);
   4837 		m_program_object_id = 0;
   4838 	}
   4839 
   4840 	/* Clean shaders */
   4841 	if (0 != m_fragment_shader_id)
   4842 	{
   4843 		gl.deleteShader(m_fragment_shader_id);
   4844 		m_fragment_shader_id = 0;
   4845 	}
   4846 
   4847 	if (0 != m_geometry_shader_id)
   4848 	{
   4849 		gl.deleteShader(m_geometry_shader_id);
   4850 		m_geometry_shader_id = 0;
   4851 	}
   4852 
   4853 	if (0 != m_tesselation_control_shader_id)
   4854 	{
   4855 		gl.deleteShader(m_tesselation_control_shader_id);
   4856 		m_tesselation_control_shader_id = 0;
   4857 	}
   4858 
   4859 	if (0 != m_tesselation_evaluation_shader_id)
   4860 	{
   4861 		gl.deleteShader(m_tesselation_evaluation_shader_id);
   4862 		m_tesselation_evaluation_shader_id = 0;
   4863 	}
   4864 
   4865 	if (0 != m_vertex_shader_id)
   4866 	{
   4867 		gl.deleteShader(m_vertex_shader_id);
   4868 		m_vertex_shader_id = 0;
   4869 	}
   4870 }
   4871 
   4872 /** Build program and query for uniform layout
   4873  *
   4874  * @param context                            Test context
   4875  * @param uniform_details                  Collection of uniform details
   4876  * @param fragment_shader_code               Fragment shader source code
   4877  * @param geometry_shader_code               Geometry shader source code
   4878  * @param tesselation_control_shader_code    Tesselation control shader source code
   4879  * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
   4880  * @param vertex_shader_code                 Vertex shader source code
   4881  **/
   4882 void GPUShaderFP64Test3::programInfo::init(deqp::Context& context, const std::vector<uniformDetails> uniform_details,
   4883 										   const glw::GLchar* fragment_shader_code,
   4884 										   const glw::GLchar* geometry_shader_code,
   4885 										   const glw::GLchar* tesselation_control_shader_code,
   4886 										   const glw::GLchar* tesselation_evaluation_shader_code,
   4887 										   const glw::GLchar* vertex_shader_code)
   4888 {
   4889 	/* GL entry points */
   4890 	const glw::Functions& gl = context.getRenderContext().getFunctions();
   4891 
   4892 	/* Names of varyings to be captured with transform feedback */
   4893 	static const glw::GLchar* varying_names[] = { m_varying_name_gs_fs_gs_result, m_varying_name_gs_fs_tcs_result,
   4894 												  m_varying_name_gs_fs_tes_result, m_varying_name_gs_fs_vs_result };
   4895 	static const glw::GLuint n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);
   4896 
   4897 	/* Create shader objects */
   4898 	m_fragment_shader_id			   = gl.createShader(GL_FRAGMENT_SHADER);
   4899 	m_geometry_shader_id			   = gl.createShader(GL_GEOMETRY_SHADER);
   4900 	m_tesselation_control_shader_id	= gl.createShader(GL_TESS_CONTROL_SHADER);
   4901 	m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
   4902 	m_vertex_shader_id				   = gl.createShader(GL_VERTEX_SHADER);
   4903 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
   4904 
   4905 	/* Create program object */
   4906 	m_program_object_id = gl.createProgram();
   4907 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
   4908 
   4909 	/* Set up names of varyings to be captured with transform feedback */
   4910 	gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
   4911 	GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
   4912 
   4913 	/* Compile shaders */
   4914 	compile(context, m_fragment_shader_id, fragment_shader_code);
   4915 	compile(context, m_geometry_shader_id, geometry_shader_code);
   4916 	compile(context, m_tesselation_control_shader_id, tesselation_control_shader_code);
   4917 	compile(context, m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
   4918 	compile(context, m_vertex_shader_id, vertex_shader_code);
   4919 
   4920 	/* Link program */
   4921 	link(context);
   4922 
   4923 	/* Inspect program object */
   4924 	/* Get index of named uniform block */
   4925 	m_uniform_block_index = gl.getUniformBlockIndex(m_program_object_id, m_uniform_block_name);
   4926 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex");
   4927 
   4928 	if (GL_INVALID_INDEX == m_uniform_block_index)
   4929 	{
   4930 		TCU_FAIL("Unifom block is inactive");
   4931 	}
   4932 
   4933 	/* Get size of named uniform block */
   4934 	gl.getActiveUniformBlockiv(m_program_object_id, m_uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &m_buffer_size);
   4935 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv");
   4936 
   4937 	if (0 == m_buffer_size)
   4938 	{
   4939 		TCU_FAIL("Unifom block size is 0");
   4940 	}
   4941 
   4942 	/* Get information about "double precision" uniforms */
   4943 	for (std::vector<uniformDetails>::const_iterator it = uniform_details.begin(), end = uniform_details.end();
   4944 		 end != it; ++it)
   4945 	{
   4946 		const glw::GLchar* uniform_name = 0;
   4947 		std::string		   uniform_name_str;
   4948 		std::stringstream  uniform_name_stream;
   4949 		glw::GLuint		   index		 = 0;
   4950 		glw::GLint		   offset		 = 0;
   4951 		glw::GLint		   matrix_stride = 0;
   4952 
   4953 		/* Uniform name = UNIFORM_BLOCK_NAME.UNIFORM_NAME */
   4954 		uniform_name_stream << m_uniform_block_name << "." << it->m_name;
   4955 
   4956 		uniform_name_str = uniform_name_stream.str();
   4957 		uniform_name	 = uniform_name_str.c_str();
   4958 
   4959 		/* Get index of uniform */
   4960 		gl.getUniformIndices(m_program_object_id, 1 /* count */, &uniform_name, &index);
   4961 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
   4962 
   4963 		if (GL_INVALID_INDEX == index)
   4964 		{
   4965 			TCU_FAIL("Unifom is inactive");
   4966 		}
   4967 
   4968 		/* Get offset of uniform */
   4969 		gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset);
   4970 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
   4971 
   4972 		if (m_invalid_uniform_offset == offset)
   4973 		{
   4974 			TCU_FAIL("Unifom has invalid offset");
   4975 		}
   4976 
   4977 		m_uniform_offsets.push_back(offset);
   4978 
   4979 		/* Get matrix stride of uniform */
   4980 		gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
   4981 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
   4982 
   4983 		if (m_invalid_uniform_matrix_stride == offset)
   4984 		{
   4985 			TCU_FAIL("Unifom has invalid matrix stride");
   4986 		}
   4987 
   4988 		m_uniform_matrix_strides.push_back(matrix_stride);
   4989 	}
   4990 }
   4991 
   4992 /** Attach shaders and link program
   4993  *
   4994  * @param context Test context
   4995  **/
   4996 void GPUShaderFP64Test3::programInfo::link(deqp::Context& context) const
   4997 {
   4998 	/* GL entry points */
   4999 	const glw::Functions& gl = context.getRenderContext().getFunctions();
   5000 
   5001 	/* Link status */
   5002 	glw::GLint status = GL_FALSE;
   5003 
   5004 	/* Attach shaders */
   5005 	gl.attachShader(m_program_object_id, m_fragment_shader_id);
   5006 	gl.attachShader(m_program_object_id, m_geometry_shader_id);
   5007 	gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
   5008 	gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
   5009 	gl.attachShader(m_program_object_id, m_vertex_shader_id);
   5010 	GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
   5011 
   5012 	/* Link */
   5013 	gl.linkProgram(m_program_object_id);
   5014 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
   5015 
   5016 	/* Get link status */
   5017 	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
   5018 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
   5019 
   5020 	/* Log link error */
   5021 	if (GL_TRUE != status)
   5022 	{
   5023 		glw::GLint				 length = 0;
   5024 		std::vector<glw::GLchar> message;
   5025 
   5026 		/* Get error log length */
   5027 		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
   5028 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
   5029 
   5030 		message.resize(length);
   5031 
   5032 		/* Get error log */
   5033 		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
   5034 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
   5035 
   5036 		/* Log */
   5037 		context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
   5038 										  << &message[0] << tcu::TestLog::EndMessage;
   5039 
   5040 		TCU_FAIL("Failed to link program");
   5041 	}
   5042 }
   5043 
   5044 /** Returns "predefined" values that will be used to fill uniform data
   5045  *
   5046  * @param type_ordinal Ordinal number of "double precision" uniform type
   5047  * @param element      Index of element in uniform
   5048  *
   5049  * @return "Predefined" value
   5050  **/
   5051 glw::GLdouble GPUShaderFP64Test3::getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const
   5052 {
   5053 	return m_base_type_ordinal + (13.0 * (glw::GLdouble)type_ordinal) +
   5054 		   ((m_base_element - (glw::GLdouble)element) / 4.0);
   5055 }
   5056 
   5057 /** Returns a reference of programInfo instance specific for given buffer layout
   5058  *
   5059  * @param uniform_data_layout Buffer layout
   5060  *
   5061  * @return Reference to an instance of programInfo
   5062  **/
   5063 const GPUShaderFP64Test3::programInfo& GPUShaderFP64Test3::getProgramInfo(uniformDataLayout uniform_data_layout) const
   5064 {
   5065 	const programInfo* program_info = 0;
   5066 
   5067 	switch (uniform_data_layout)
   5068 	{
   5069 	case PACKED:
   5070 
   5071 		program_info = &m_packed_program;
   5072 
   5073 		break;
   5074 
   5075 	case SHARED:
   5076 
   5077 		program_info = &m_shared_program;
   5078 
   5079 		break;
   5080 
   5081 	case STD140:
   5082 
   5083 		program_info = &m_std140_program;
   5084 
   5085 		break;
   5086 	}
   5087 
   5088 	return *program_info;
   5089 }
   5090 
   5091 /** Get "name" of buffer layout
   5092  *
   5093  * @param uniform_data_layout Buffer layout
   5094  *
   5095  * @return "Name" of layout
   5096  **/
   5097 const glw::GLchar* GPUShaderFP64Test3::getUniformLayoutName(uniformDataLayout uniform_data_layout) const
   5098 {
   5099 	const glw::GLchar* layout = "";
   5100 
   5101 	switch (uniform_data_layout)
   5102 	{
   5103 	case PACKED:
   5104 		layout = "packed";
   5105 		break;
   5106 	case SHARED:
   5107 		layout = "shared";
   5108 		break;
   5109 	case STD140:
   5110 		layout = "std140";
   5111 		break;
   5112 	}
   5113 
   5114 	return layout;
   5115 }
   5116 
   5117 /** Prepare programInfo instance for specific buffer layout
   5118  *
   5119  * @param program_info        Instance of programInfo
   5120  * @param uniform_data_layout Buffer layout
   5121  **/
   5122 void GPUShaderFP64Test3::prepareProgram(programInfo& program_info, uniformDataLayout uniform_data_layout) const
   5123 {
   5124 	/* Storage for shader source code */
   5125 	std::stringstream fragment_shader_code;
   5126 	std::stringstream geometry_shader_code;
   5127 	std::stringstream tess_control_shader_code;
   5128 	std::stringstream tess_eval_shader_code;
   5129 	std::stringstream vertex_shader_code;
   5130 
   5131 	/* Write preambles */
   5132 	writePreamble(fragment_shader_code, FRAGMENT_SHADER);
   5133 	writePreamble(geometry_shader_code, GEOMETRY_SHADER);
   5134 	writePreamble(tess_control_shader_code, TESS_CONTROL_SHADER);
   5135 	writePreamble(tess_eval_shader_code, TESS_EVAL_SHADER);
   5136 	writePreamble(vertex_shader_code, VERTEX_SHADER);
   5137 
   5138 	/* Write definition of named uniform block */
   5139 	writeUniformBlock(fragment_shader_code, uniform_data_layout);
   5140 	writeUniformBlock(geometry_shader_code, uniform_data_layout);
   5141 	writeUniformBlock(tess_control_shader_code, uniform_data_layout);
   5142 	writeUniformBlock(tess_eval_shader_code, uniform_data_layout);
   5143 	writeUniformBlock(vertex_shader_code, uniform_data_layout);
   5144 
   5145 	/* Write definitions of varyings */
   5146 	writeVaryingDeclarations(fragment_shader_code, FRAGMENT_SHADER);
   5147 	writeVaryingDeclarations(geometry_shader_code, GEOMETRY_SHADER);
   5148 	writeVaryingDeclarations(tess_control_shader_code, TESS_CONTROL_SHADER);
   5149 	writeVaryingDeclarations(tess_eval_shader_code, TESS_EVAL_SHADER);
   5150 	writeVaryingDeclarations(vertex_shader_code, VERTEX_SHADER);
   5151 
   5152 	/* Write main routine */
   5153 	writeMainBody(fragment_shader_code, FRAGMENT_SHADER);
   5154 	writeMainBody(geometry_shader_code, GEOMETRY_SHADER);
   5155 	writeMainBody(tess_control_shader_code, TESS_CONTROL_SHADER);
   5156 	writeMainBody(tess_eval_shader_code, TESS_EVAL_SHADER);
   5157 	writeMainBody(vertex_shader_code, VERTEX_SHADER);
   5158 
   5159 	/* Init programInfo instance */
   5160 	program_info.init(m_context, m_uniform_details, fragment_shader_code.str().c_str(),
   5161 					  geometry_shader_code.str().c_str(), tess_control_shader_code.str().c_str(),
   5162 					  tess_eval_shader_code.str().c_str(), vertex_shader_code.str().c_str());
   5163 }
   5164 
   5165 /** Prepare uniform buffer
   5166  *
   5167  * @param program_info   Instance of programInfo
   5168  * @param verify_offsets If uniform offsets should be verified against expected values
   5169  *
   5170  * @return false if uniform offsets verification result is failure, true otherwise
   5171  **/
   5172 bool GPUShaderFP64Test3::prepareUniformBuffer(const programInfo& program_info, bool verify_offsets) const
   5173 {
   5174 	const glw::GLuint							buffer_size = program_info.m_buffer_size;
   5175 	const glw::Functions&						gl			= m_context.getRenderContext().getFunctions();
   5176 	bool										offset_verification_result = true;
   5177 	glw::GLuint									type_ordinal			   = 1;
   5178 	std::vector<uniformDetails>::const_iterator it_uniform_details		   = m_uniform_details.begin();
   5179 	std::vector<glw::GLint>::const_iterator		it_uniform_offsets		   = program_info.m_uniform_offsets.begin();
   5180 	std::vector<glw::GLint>::const_iterator it_uniform_matrix_strides = program_info.m_uniform_matrix_strides.begin();
   5181 
   5182 	/* Prepare storage for uniform buffer data */
   5183 	std::vector<glw::GLubyte> buffer_data;
   5184 	buffer_data.resize(buffer_size);
   5185 
   5186 	/* For each "double precision" uniform */
   5187 	for (/* start conditions already set up */; m_uniform_details.end() != it_uniform_details;
   5188 		 ++it_uniform_details, ++it_uniform_offsets, ++it_uniform_matrix_strides, ++type_ordinal)
   5189 	{
   5190 		const glw::GLint  matrix_stride  = *it_uniform_matrix_strides;
   5191 		const glw::GLuint n_columns		 = it_uniform_details->m_n_columns;
   5192 		const glw::GLuint n_elements	 = it_uniform_details->m_n_elements;
   5193 		const glw::GLuint column_length  = n_elements / n_columns;
   5194 		const glw::GLint  uniform_offset = *it_uniform_offsets;
   5195 
   5196 		/* For each element of uniform */
   5197 		for (glw::GLuint element = 0; element < n_elements; ++element)
   5198 		{
   5199 			const glw::GLuint   column		= element / column_length;
   5200 			const glw::GLuint   column_elem = element % column_length;
   5201 			const glw::GLdouble value		= getExpectedValue(type_ordinal, element);
   5202 			const glw::GLuint   value_offset =
   5203 				static_cast<glw::GLuint>(uniform_offset + column * matrix_stride + column_elem * sizeof(glw::GLdouble));
   5204 
   5205 			glw::GLdouble* value_dst = (glw::GLdouble*)&buffer_data[value_offset];
   5206 
   5207 			/* Store value */
   5208 			*value_dst = value;
   5209 		}
   5210 
   5211 		/* Uniform offset verification */
   5212 		if (true == verify_offsets)
   5213 		{
   5214 			const glw::GLint expected_offset = it_uniform_details->m_expected_std140_offset;
   5215 
   5216 			if (expected_offset != uniform_offset)
   5217 			{
   5218 				if (true == offset_verification_result)
   5219 				{
   5220 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage;
   5221 				}
   5222 
   5223 				m_context.getTestContext().getLog()
   5224 					<< tcu::TestLog::Message << "Uniform: " << it_uniform_details->m_name
   5225 					<< " has offset: " << uniform_offset << ". Expected offset: " << expected_offset
   5226 					<< tcu::TestLog::EndMessage;
   5227 
   5228 				offset_verification_result = false;
   5229 			}
   5230 		}
   5231 	}
   5232 
   5233 	/* Update uniform buffer with prepared data */
   5234 	gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id);
   5235 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
   5236 
   5237 	gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &buffer_data[0], GL_STATIC_DRAW);
   5238 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
   5239 
   5240 	/* Bind uniform buffer as data source for named uniform block */
   5241 	gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0, buffer_size);
   5242 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
   5243 
   5244 	gl.uniformBlockBinding(program_info.m_program_object_id, program_info.m_uniform_block_index, 0 /* binding */);
   5245 	GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding");
   5246 
   5247 	/* Done */
   5248 	return offset_verification_result;
   5249 }
   5250 
   5251 /** Prepare data, execute draw call and verify results
   5252  *
   5253  * @param uniform_data_layout
   5254  *
   5255  * @return true if test pass, false otherwise
   5256  **/
   5257 bool GPUShaderFP64Test3::test(uniformDataLayout uniform_data_layout) const
   5258 {
   5259 	bool				  are_offsets_verified		 = (STD140 == uniform_data_layout);
   5260 	const glw::Functions& gl						 = m_context.getRenderContext().getFunctions();
   5261 	bool				  offset_verification_result = true;
   5262 	const programInfo&	program_info				 = getProgramInfo(uniform_data_layout);
   5263 	bool				  result					 = true;
   5264 
   5265 	/* Set up program */
   5266 	gl.useProgram(program_info.m_program_object_id);
   5267 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   5268 
   5269 	/* Prepare uniform buffer */
   5270 	offset_verification_result = prepareUniformBuffer(program_info, are_offsets_verified);
   5271 
   5272 	if (true == are_offsets_verified && false == offset_verification_result)
   5273 	{
   5274 		/* Offsets verification failure was already reported, add info about buffer layout */
   5275 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5276 											<< "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout)
   5277 											<< tcu::TestLog::EndMessage;
   5278 
   5279 		result = false;
   5280 	}
   5281 
   5282 	/* Set up transform feedback buffer */
   5283 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_transform_feedback_buffer_id, 0, 4 * sizeof(glw::GLint));
   5284 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   5285 
   5286 	/* Begin transform feedback */
   5287 	gl.beginTransformFeedback(GL_POINTS);
   5288 	GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
   5289 
   5290 	/* Execute draw call for singe vertex */
   5291 	gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
   5292 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
   5293 
   5294 	/* Stop transform feedback */
   5295 	gl.endTransformFeedback();
   5296 	GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
   5297 
   5298 	/* Verify results */
   5299 	if (false == verifyResults())
   5300 	{
   5301 		/* Result verificatioon failure was already reported, add info about layout */
   5302 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5303 											<< "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout)
   5304 											<< tcu::TestLog::EndMessage;
   5305 
   5306 		result = false;
   5307 	}
   5308 
   5309 	/* Done */
   5310 	return result;
   5311 }
   5312 
   5313 void GPUShaderFP64Test3::testInit()
   5314 {
   5315 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5316 
   5317 	/* Uniform block declaration with std140 offsets calculated
   5318 	 *                       | align | loc_req | begins | ends | offset in bytes | imp |
   5319 	 * ivec3   dummy1[3]     |     4 |      12 |      0 |   12 |               0 |     |
   5320 	 * double  double_value  |     2 |       2 |     12 |   14 |              48 | XXX |
   5321 	 * bool    dummy2        |     1 |       1 |     14 |   15 |              56 |     |
   5322 	 * dvec2   dvec2_value   |     4 |       4 |     16 |   20 |              64 | XXX |
   5323 	 * bvec3   dummy3        |     4 |       4 |     20 |   24 |              80 |     |
   5324 	 * dvec3   dvec3_value   |     8 |       8 |     24 |   32 |              96 | XXX |
   5325 	 * int     dummy4[3]     |     4 |      12 |     32 |   44 |             128 |     |
   5326 	 * dvec4   dvec4_value   |     8 |       8 |     48 |   56 |             192 | XXX |
   5327 	 * bool    dummy5        |     1 |       1 |     56 |   57 |             224 |     |
   5328 	 * bool    dummy6[2]     |     4 |       8 |     60 |   68 |             240 |     |
   5329 	 * dmat2   dmat2_value   |     4 |       8 |     68 |   76 |             272 | XXX |
   5330 	 * dmat3   dmat3_value   |     8 |      24 |     80 |  104 |             320 | XXX |
   5331 	 * bool    dummy7        |     1 |       1 |    104 |  105 |             416 |     |
   5332 	 * dmat4   dmat4_value   |     8 |      32 |    112 |  144 |             448 | XXX |
   5333 	 * dmat2x3 dmat2x3_value |     8 |      16 |    144 |  160 |             576 | XXX |
   5334 	 * uvec3   dummy8        |     4 |       4 |    160 |  164 |             640 |     |
   5335 	 * dmat2x4 dmat2x4_value |     8 |      16 |    168 |  184 |             672 | XXX |
   5336 	 * dmat3x2 dmat3x2_value |     4 |      12 |    184 |  196 |             736 | XXX |
   5337 	 * bool    dummy9        |     1 |       1 |    196 |  197 |             784 |     |
   5338 	 * dmat3x4 dmat3x4_value |     8 |      24 |    200 |  224 |             800 | XXX |
   5339 	 * int     dummy10       |     1 |       1 |    224 |  225 |             896 |     |
   5340 	 * dmat4x2 dmat4x2_value |     4 |      16 |    228 |  244 |             912 | XXX |
   5341 	 * dmat4x3 dmat4x3_value |     8 |      32 |    248 |  280 |             992 | XXX |
   5342 	 */
   5343 
   5344 	/* Prepare "double precision" unfiorms' details */
   5345 	m_uniform_details.push_back(uniformDetails(48 /* off */, "double_value" /* name */, 1 /* n_columns */,
   5346 											   1 /* n_elements */, "double" /* type_name */));
   5347 	m_uniform_details.push_back(uniformDetails(64 /* off */, "dvec2_value" /* name */, 1 /* n_columns */,
   5348 											   2 /* n_elements */, "dvec2" /* type_name */));
   5349 	m_uniform_details.push_back(uniformDetails(96 /* off */, "dvec3_value" /* name */, 1 /* n_columns */,
   5350 											   3 /* n_elements */, "dvec3" /* type_name */));
   5351 	m_uniform_details.push_back(uniformDetails(192 /* off */, "dvec4_value" /* name */, 1 /* n_columns */,
   5352 											   4 /* n_elements */, "dvec4" /* type_name */));
   5353 	m_uniform_details.push_back(uniformDetails(272 /* off */, "dmat2_value" /* name */, 2 /* n_columns */,
   5354 											   4 /* n_elements */, "dmat2" /* type_name */));
   5355 	m_uniform_details.push_back(uniformDetails(320 /* off */, "dmat3_value" /* name */, 3 /* n_columns */,
   5356 											   9 /* n_elements */, "dmat3" /* type_name */));
   5357 	m_uniform_details.push_back(uniformDetails(448 /* off */, "dmat4_value" /* name */, 4 /* n_columns */,
   5358 											   16 /* n_elements */, "dmat4" /* type_name */));
   5359 	m_uniform_details.push_back(uniformDetails(576 /* off */, "dmat2x3_value" /* name */, 2 /* n_columns */,
   5360 											   6 /* n_elements */, "dmat2x3" /* type_name */));
   5361 	m_uniform_details.push_back(uniformDetails(672 /* off */, "dmat2x4_value" /* name */, 2 /* n_columns */,
   5362 											   8 /* n_elements */, "dmat2x4" /* type_name */));
   5363 	m_uniform_details.push_back(uniformDetails(736 /* off */, "dmat3x2_value" /* name */, 3 /* n_columns */,
   5364 											   6 /* n_elements */, "dmat3x2" /* type_name */));
   5365 	m_uniform_details.push_back(uniformDetails(800 /* off */, "dmat3x4_value" /* name */, 3 /* n_columns */,
   5366 											   12 /* n_elements */, "dmat3x4" /* type_name */));
   5367 	m_uniform_details.push_back(uniformDetails(912 /* off */, "dmat4x2_value" /* name */, 4 /* n_columns */,
   5368 											   8 /* n_elements */, "dmat4x2" /* type_name */));
   5369 	m_uniform_details.push_back(uniformDetails(992 /* off */, "dmat4x3_value" /* name */, 4 /* n_columns */,
   5370 											   12 /* n_elements */, "dmat4x3" /* type_name */));
   5371 
   5372 	/* Get random values for getExpectedValue */
   5373 	m_base_element		= (glw::GLdouble)(rand() % 13);
   5374 	m_base_type_ordinal = (glw::GLdouble)(rand() % 213);
   5375 
   5376 	/* Prepare programInfos for all buffer layouts */
   5377 	prepareProgram(m_packed_program, PACKED);
   5378 	prepareProgram(m_shared_program, SHARED);
   5379 	prepareProgram(m_std140_program, STD140);
   5380 
   5381 	/* Generate buffers */
   5382 	gl.genBuffers(1, &m_transform_feedback_buffer_id);
   5383 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
   5384 
   5385 	gl.genBuffers(1, &m_uniform_buffer_id);
   5386 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
   5387 
   5388 	/* Prepare transform feedback buffer */
   5389 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
   5390 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
   5391 
   5392 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), 0 /* data */, GL_DYNAMIC_COPY);
   5393 	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
   5394 
   5395 	/* Prepare texture for color attachment 0 */
   5396 	gl.genTextures(1, &m_color_texture_id);
   5397 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
   5398 
   5399 	gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id);
   5400 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   5401 
   5402 	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_R32I, 1 /* width */, 1 /* height */);
   5403 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
   5404 
   5405 	/* Prepare FBO with color attachment 0 */
   5406 	gl.genFramebuffers(1, &m_framebuffer_id);
   5407 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
   5408 
   5409 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
   5410 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
   5411 
   5412 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture_id,
   5413 							0 /* level */);
   5414 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
   5415 
   5416 	gl.viewport(0 /* x */, 0 /* y */, 1 /* width */, 1 /* height */);
   5417 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
   5418 
   5419 	/* Prepare VAO */
   5420 	gl.genVertexArrays(1, &m_vertex_array_object_id);
   5421 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
   5422 
   5423 	gl.bindVertexArray(m_vertex_array_object_id);
   5424 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
   5425 
   5426 	/* Tesselation patch set up */
   5427 	gl.patchParameteri(GL_PATCH_VERTICES, 1);
   5428 	GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
   5429 }
   5430 
   5431 /** Verify contents of transform feedback buffer and framebuffer's color attachment 0
   5432  *
   5433  * @return true if all values are as expected, false otherwise
   5434  **/
   5435 bool GPUShaderFP64Test3::verifyResults() const
   5436 {
   5437 	glw::GLint*			  feedback_data			  = 0;
   5438 	bool				  fragment_shader_result  = false;
   5439 	bool				  geometry_shader_result  = false;
   5440 	const glw::Functions& gl					  = m_context.getRenderContext().getFunctions();
   5441 	bool				  tess_ctrl_shader_result = false;
   5442 	bool				  tess_eval_shader_result = false;
   5443 	bool				  vertex_shader_result	= false;
   5444 
   5445 	/* Prepare storage for testure data */
   5446 	std::vector<glw::GLint> image_data;
   5447 	image_data.resize(1);
   5448 
   5449 	/* Get texture contents */
   5450 	gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id);
   5451 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
   5452 
   5453 	gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]);
   5454 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
   5455 
   5456 	/* Get transform feedback data */
   5457 	feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   5458 	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
   5459 
   5460 	/* Verify results */
   5461 	fragment_shader_result  = (m_result_success == image_data[0]);
   5462 	geometry_shader_result  = (m_result_success == feedback_data[0]);
   5463 	tess_ctrl_shader_result = (m_result_success == feedback_data[1]);
   5464 	tess_eval_shader_result = (m_result_success == feedback_data[2]);
   5465 	vertex_shader_result	= (m_result_success == feedback_data[3]);
   5466 
   5467 	/* Unmap transform feedback buffer */
   5468 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5469 	GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
   5470 
   5471 	/* Set result */
   5472 	if (true != (fragment_shader_result && geometry_shader_result && tess_ctrl_shader_result &&
   5473 				 tess_eval_shader_result && vertex_shader_result))
   5474 	{
   5475 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage;
   5476 
   5477 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5478 											<< "Vertex shader stage result: " << vertex_shader_result
   5479 											<< tcu::TestLog::EndMessage;
   5480 
   5481 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5482 											<< "Tesselation control shader stage result: " << tess_ctrl_shader_result
   5483 											<< tcu::TestLog::EndMessage;
   5484 
   5485 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5486 											<< "Tesselation evaluation shader stage result: " << tess_eval_shader_result
   5487 											<< tcu::TestLog::EndMessage;
   5488 
   5489 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5490 											<< "Geometry shader stage result: " << geometry_shader_result
   5491 											<< tcu::TestLog::EndMessage;
   5492 
   5493 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   5494 											<< "Fragment shader stage result: " << fragment_shader_result
   5495 											<< tcu::TestLog::EndMessage;
   5496 
   5497 		return false;
   5498 	}
   5499 	else
   5500 	{
   5501 		return true;
   5502 	}
   5503 }
   5504 
   5505 /** Write main routine of <shader_stage> shader to stream
   5506  *
   5507  * @param stream       Output stream with source code of shader
   5508  * @param shader_stage Shader stage
   5509  **/
   5510 void GPUShaderFP64Test3::writeMainBody(std::ostream& stream, shaderStage shader_stage) const
   5511 {
   5512 	glw::GLuint		   type_ordinal = 1;
   5513 	const glw::GLchar* varying_name = "";
   5514 
   5515 	/* Select name for varying that will hold result of "that" shader_stage */
   5516 	switch (shader_stage)
   5517 	{
   5518 	case FRAGMENT_SHADER:
   5519 		varying_name = m_varying_name_fs_out_fs_result;
   5520 		break;
   5521 	case GEOMETRY_SHADER:
   5522 		varying_name = m_varying_name_gs_fs_gs_result;
   5523 		break;
   5524 	case TESS_CONTROL_SHADER:
   5525 		varying_name = m_varying_name_tcs_tes_tcs_result;
   5526 		break;
   5527 	case TESS_EVAL_SHADER:
   5528 		varying_name = m_varying_name_tes_gs_tes_result;
   5529 		break;
   5530 	case VERTEX_SHADER:
   5531 		varying_name = m_varying_name_vs_tcs_vs_result;
   5532 		break;
   5533 	}
   5534 
   5535 	/* void main() */
   5536 	stream << "void main()\n"
   5537 			  "{\n";
   5538 
   5539 	/* Tesselation levels output */
   5540 	if (TESS_CONTROL_SHADER == shader_stage)
   5541 	{
   5542 		stream << "gl_TessLevelOuter[0] = 1.0;\n"
   5543 				  "gl_TessLevelOuter[1] = 1.0;\n"
   5544 				  "gl_TessLevelOuter[2] = 1.0;\n"
   5545 				  "gl_TessLevelOuter[3] = 1.0;\n"
   5546 				  "gl_TessLevelInner[0] = 1.0;\n"
   5547 				  "gl_TessLevelInner[1] = 1.0;\n"
   5548 				  "\n";
   5549 	}
   5550 
   5551 	/* For each "double precision" uniform
   5552 	 *
   5553 	 * [else] if (TYPE_NAME(PREDIFINED_VALUES) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME)
   5554 	 * {
   5555 	 *     VARYING_NAME = m_result_failure;
   5556 	 * }
   5557 	 */
   5558 	for (std::vector<uniformDetails>::const_iterator it = m_uniform_details.begin(), end = m_uniform_details.end();
   5559 		 end != it; ++it, ++type_ordinal)
   5560 	{
   5561 		stream << "    ";
   5562 
   5563 		/* First comparison is done with if, next with else if */
   5564 		if (1 != type_ordinal)
   5565 		{
   5566 			stream << "else ";
   5567 		}
   5568 
   5569 		/* if (TYPE_NAME( */
   5570 		stream << "if (" << it->m_type_name << "(";
   5571 
   5572 		/* PREDIFINED_VALUES */
   5573 		for (glw::GLuint element = 0; element < it->m_n_elements; ++element)
   5574 		{
   5575 			stream << getExpectedValue(type_ordinal, element);
   5576 
   5577 			/* Separate with comma */
   5578 			if (it->m_n_elements != element + 1)
   5579 			{
   5580 				stream << ", ";
   5581 			}
   5582 		}
   5583 
   5584 		/*
   5585 		 * ) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME)
   5586 		 * {
   5587 		 *     VARYING_NAME
   5588 		 */
   5589 		stream << ") != " << m_uniform_block_instance_name << "." << it->m_name << ")\n"
   5590 																				   "    {\n"
   5591 																				   "        "
   5592 			   << varying_name;
   5593 
   5594 		/* Tesselation control outputs have to be arrays indexed with gl_InvocationID */
   5595 		if (TESS_CONTROL_SHADER == shader_stage)
   5596 		{
   5597 			stream << "[gl_InvocationID]";
   5598 		}
   5599 
   5600 		/*
   5601 		 * = m_result_failure;
   5602 		 * }
   5603 		 */
   5604 		stream << " = " << m_result_failure << ";\n"
   5605 			   << "    }\n";
   5606 	}
   5607 
   5608 	/* If all comparisons are ok
   5609 	 *
   5610 	 *     else
   5611 	 *     {
   5612 	 *         VARYING_NAME = m_result_success;
   5613 	 *     }
   5614 	 */
   5615 
   5616 	/*
   5617 	 * else
   5618 	 * {
   5619 	 *     VARYING_NAME
   5620 	 */
   5621 	stream << "    else\n"
   5622 			  "    {\n"
   5623 			  "        "
   5624 		   << varying_name;
   5625 
   5626 	/* Tesselation control outputs have to be arrays indexed with gl_InvocationID */
   5627 	if (TESS_CONTROL_SHADER == shader_stage)
   5628 	{
   5629 		stream << "[gl_InvocationID]";
   5630 	}
   5631 
   5632 	/*
   5633 	 * = m_result_success;
   5634 	 * }
   5635 	 *
   5636 	 */
   5637 	stream << " = " << m_result_success << ";\n"
   5638 		   << "    }\n"
   5639 		   << "\n";
   5640 
   5641 	/* For each pair of "input/output" varyings
   5642 	 *
   5643 	 * OUTPUT_VARYING_NAME = INPUT_VARYING_NAME;
   5644 	 **/
   5645 	writeVaryingPassthrough(stream, shader_stage);
   5646 
   5647 	/* Geometry shader have to emit vertex */
   5648 	if (GEOMETRY_SHADER == shader_stage)
   5649 	{
   5650 		stream << "\n"
   5651 				  "gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"
   5652 				  "EmitVertex();\n"
   5653 				  "EndPrimitive();\n";
   5654 	}
   5655 
   5656 	/* Close scope of main */
   5657 	stream << "}\n\n";
   5658 }
   5659 
   5660 /** Write shader preamble to stream
   5661  *
   5662  * @param stream       Output stream with source code of shader
   5663  * @param shader_stage Shader stage
   5664  **/
   5665 void GPUShaderFP64Test3::writePreamble(std::ostream& stream, shaderStage shader_stage) const
   5666 {
   5667 	stream << "#version 400 core\n"
   5668 			  "\n"
   5669 			  "precision highp float;\n"
   5670 			  "\n";
   5671 
   5672 	switch (shader_stage)
   5673 	{
   5674 	case FRAGMENT_SHADER:
   5675 		break;
   5676 	case GEOMETRY_SHADER:
   5677 		stream << "layout(points)                   in;\n"
   5678 				  "layout(points, max_vertices = 1) out;\n"
   5679 				  "\n";
   5680 		break;
   5681 	case TESS_CONTROL_SHADER:
   5682 		stream << "layout(vertices = 1) out;\n"
   5683 				  "\n";
   5684 		break;
   5685 	case TESS_EVAL_SHADER:
   5686 		stream << "layout(isolines, point_mode) in;\n"
   5687 				  "\n";
   5688 		break;
   5689 	case VERTEX_SHADER:
   5690 		break;
   5691 	}
   5692 }
   5693 
   5694 /** Write name uniform blcok definition with specific layout to stream
   5695  *
   5696  * @param stream              Output stream with source code of shader
   5697  * @param uniform_data_layout Buffer layout
   5698  **/
   5699 void GPUShaderFP64Test3::writeUniformBlock(std::ostream& stream, uniformDataLayout uniform_data_layout) const
   5700 {
   5701 	const glw::GLchar* layout = getUniformLayoutName(uniform_data_layout);
   5702 
   5703 	stream << "layout(" << layout << ") uniform " << m_uniform_block_name << "\n"
   5704 																			 "{\n"
   5705 																			 "    ivec3   dummy1[3];\n"
   5706 																			 "    double  double_value;\n"
   5707 																			 "    bool    dummy2;\n"
   5708 																			 "    dvec2   dvec2_value;\n"
   5709 																			 "    bvec3   dummy3;\n"
   5710 																			 "    dvec3   dvec3_value;\n"
   5711 																			 "    int     dummy4[3];\n"
   5712 																			 "    dvec4   dvec4_value;\n"
   5713 																			 "    bool    dummy5;\n"
   5714 																			 "    bool    dummy6[2];\n"
   5715 																			 "    dmat2   dmat2_value;\n"
   5716 																			 "    dmat3   dmat3_value;\n"
   5717 																			 "    bool    dummy7;\n"
   5718 																			 "    dmat4   dmat4_value;\n"
   5719 																			 "    dmat2x3 dmat2x3_value;\n"
   5720 																			 "    uvec3   dummy8;\n"
   5721 																			 "    dmat2x4 dmat2x4_value;\n"
   5722 																			 "    dmat3x2 dmat3x2_value;\n"
   5723 																			 "    bool    dummy9;\n"
   5724 																			 "    dmat3x4 dmat3x4_value;\n"
   5725 																			 "    int     dummy10;\n"
   5726 																			 "    dmat4x2 dmat4x2_value;\n"
   5727 																			 "    dmat4x3 dmat4x3_value;\n"
   5728 																			 "} "
   5729 		   << m_uniform_block_instance_name << ";\n";
   5730 
   5731 	stream << "\n";
   5732 }
   5733 
   5734 /** Write definitions of varyings specific for given <shader_stage> to stream
   5735  *
   5736  * @param stream       Output stream with source code of shader
   5737  * @param shader_stage Shader stage
   5738  **/
   5739 void GPUShaderFP64Test3::writeVaryingDeclarations(std::ostream& stream, shaderStage shader_stage) const
   5740 {
   5741 	static const glw::GLchar* const varying_type = "int";
   5742 
   5743 	switch (shader_stage)
   5744 	{
   5745 	case FRAGMENT_SHADER:
   5746 
   5747 		/* In */
   5748 		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n";
   5749 		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n";
   5750 		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n";
   5751 		stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n";
   5752 
   5753 		stream << "\n";
   5754 
   5755 		/* Out */
   5756 		stream << "layout (location = 0) out " << varying_type << " " << m_varying_name_fs_out_fs_result << ";\n";
   5757 
   5758 		break;
   5759 
   5760 	case GEOMETRY_SHADER:
   5761 
   5762 		/* In */
   5763 		stream << "in  " << varying_type << " " << m_varying_name_tes_gs_tcs_result << "[];\n";
   5764 		stream << "in  " << varying_type << " " << m_varying_name_tes_gs_tes_result << "[];\n";
   5765 		stream << "in  " << varying_type << " " << m_varying_name_tes_gs_vs_result << "[];\n";
   5766 
   5767 		stream << "\n";
   5768 
   5769 		/* Out */
   5770 		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n";
   5771 		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n";
   5772 		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n";
   5773 		stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n";
   5774 
   5775 		break;
   5776 
   5777 	case TESS_CONTROL_SHADER:
   5778 
   5779 		/* In */
   5780 		stream << "in  " << varying_type << " " << m_varying_name_vs_tcs_vs_result << "[];\n";
   5781 
   5782 		stream << "\n";
   5783 
   5784 		/* Out */
   5785 		stream << "out " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n";
   5786 		stream << "out " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n";
   5787 
   5788 		break;
   5789 
   5790 	case TESS_EVAL_SHADER:
   5791 
   5792 		/* In */
   5793 		stream << "in  " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n";
   5794 		stream << "in  " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n";
   5795 
   5796 		stream << "\n";
   5797 
   5798 		/* Out */
   5799 		stream << "out " << varying_type << " " << m_varying_name_tes_gs_tcs_result << ";\n";
   5800 		stream << "out " << varying_type << " " << m_varying_name_tes_gs_tes_result << ";\n";
   5801 		stream << "out " << varying_type << " " << m_varying_name_tes_gs_vs_result << ";\n";
   5802 
   5803 		break;
   5804 
   5805 	case VERTEX_SHADER:
   5806 
   5807 		/* Out */
   5808 		stream << "out " << varying_type << " " << m_varying_name_vs_tcs_vs_result << ";\n";
   5809 
   5810 		break;
   5811 	}
   5812 
   5813 	stream << "\n";
   5814 }
   5815 
   5816 /** Write passthrough code of "input/output" varying pairs to stream
   5817  *
   5818  * @param stream       Output stream with source code of shader
   5819  * @param shader_stage Shader stage
   5820  **/
   5821 void GPUShaderFP64Test3::writeVaryingPassthrough(std::ostream& stream, shaderStage shader_stage) const
   5822 {
   5823 	switch (shader_stage)
   5824 	{
   5825 	case FRAGMENT_SHADER:
   5826 		break;
   5827 
   5828 	case GEOMETRY_SHADER:
   5829 
   5830 		stream << "    " << m_varying_name_gs_fs_tcs_result << " = " << m_varying_name_tes_gs_tcs_result << "[0];\n";
   5831 		stream << "    " << m_varying_name_gs_fs_tes_result << " = " << m_varying_name_tes_gs_tes_result << "[0];\n";
   5832 		stream << "    " << m_varying_name_gs_fs_vs_result << " = " << m_varying_name_tes_gs_vs_result << "[0];\n";
   5833 
   5834 		break;
   5835 
   5836 	case TESS_CONTROL_SHADER:
   5837 
   5838 		stream << "    " << m_varying_name_tcs_tes_vs_result
   5839 			   << "[gl_InvocationID] = " << m_varying_name_vs_tcs_vs_result << "[0];\n";
   5840 
   5841 		break;
   5842 
   5843 	case TESS_EVAL_SHADER:
   5844 
   5845 		stream << "    " << m_varying_name_tes_gs_tcs_result << " = " << m_varying_name_tcs_tes_tcs_result << "[0];\n";
   5846 		stream << "    " << m_varying_name_tes_gs_vs_result << " = " << m_varying_name_tcs_tes_vs_result << "[0];\n";
   5847 
   5848 		break;
   5849 
   5850 	case VERTEX_SHADER:
   5851 
   5852 		break;
   5853 	}
   5854 }
   5855 
   5856 /** Constructor. Sets all uniform locations to -1 and sets all
   5857  *  values to 0.
   5858  */
   5859 GPUShaderFP64Test4::_data::_data()
   5860 {
   5861 	memset(&uniform_double, 0, sizeof(uniform_double));
   5862 	memset(uniform_dvec2, 0, sizeof(uniform_dvec2));
   5863 	memset(uniform_dvec2_arr, 0, sizeof(uniform_dvec2_arr));
   5864 	memset(uniform_dvec3, 0, sizeof(uniform_dvec3));
   5865 	memset(uniform_dvec3_arr, 0, sizeof(uniform_dvec3_arr));
   5866 	memset(uniform_dvec4, 0, sizeof(uniform_dvec4));
   5867 	memset(uniform_dvec4_arr, 0, sizeof(uniform_dvec4_arr));
   5868 
   5869 	uniform_location_double		   = -1;
   5870 	uniform_location_double_arr[0] = -1;
   5871 	uniform_location_double_arr[1] = -1;
   5872 	uniform_location_dvec2		   = -1;
   5873 	uniform_location_dvec2_arr[0]  = -1;
   5874 	uniform_location_dvec2_arr[1]  = -1;
   5875 	uniform_location_dvec3		   = -1;
   5876 	uniform_location_dvec3_arr[0]  = -1;
   5877 	uniform_location_dvec3_arr[1]  = -1;
   5878 	uniform_location_dvec4		   = -1;
   5879 	uniform_location_dvec4_arr[0]  = -1;
   5880 	uniform_location_dvec4_arr[1]  = -1;
   5881 }
   5882 
   5883 /** Constructor
   5884  *
   5885  *  @param context Rendering context.
   5886  */
   5887 GPUShaderFP64Test4::GPUShaderFP64Test4(deqp::Context& context)
   5888 	: TestCase(context, "state_query", "Verifies glGet*() calls, as well as \"program interface query\"-specific tools"
   5889 									   " report correct properties of & values assigned to double-precision uniforms.")
   5890 	, m_has_test_passed(true)
   5891 	, m_uniform_name_buffer(0)
   5892 	, m_cs_id(0)
   5893 	, m_fs_id(0)
   5894 	, m_gs_id(0)
   5895 	, m_po_cs_id(0)
   5896 	, m_po_noncs_id(0)
   5897 	, m_tc_id(0)
   5898 	, m_te_id(0)
   5899 	, m_vs_id(0)
   5900 {
   5901 	/* Left blank intentionally */
   5902 }
   5903 
   5904 /** Deinitializes all GL objects, as well as releases all bufers, that may
   5905  *  have beenallocated or  created during test execution.
   5906  **/
   5907 void GPUShaderFP64Test4::deinit()
   5908 {
   5909 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5910 
   5911 	if (m_cs_id != 0)
   5912 	{
   5913 		gl.deleteShader(m_cs_id);
   5914 
   5915 		m_cs_id = 0;
   5916 	}
   5917 
   5918 	if (m_fs_id != 0)
   5919 	{
   5920 		gl.deleteShader(m_fs_id);
   5921 
   5922 		m_fs_id = 0;
   5923 	}
   5924 
   5925 	if (m_gs_id != 0)
   5926 	{
   5927 		gl.deleteShader(m_gs_id);
   5928 
   5929 		m_gs_id = 0;
   5930 	}
   5931 
   5932 	if (m_po_cs_id != 0)
   5933 	{
   5934 		gl.deleteProgram(m_po_cs_id);
   5935 
   5936 		m_po_cs_id = 0;
   5937 	}
   5938 
   5939 	if (m_po_noncs_id != 0)
   5940 	{
   5941 		gl.deleteProgram(m_po_noncs_id);
   5942 
   5943 		m_po_noncs_id = 0;
   5944 	}
   5945 
   5946 	if (m_tc_id != 0)
   5947 	{
   5948 		gl.deleteShader(m_tc_id);
   5949 
   5950 		m_tc_id = 0;
   5951 	}
   5952 
   5953 	if (m_te_id != 0)
   5954 	{
   5955 		gl.deleteShader(m_te_id);
   5956 
   5957 		m_te_id = 0;
   5958 	}
   5959 
   5960 	if (m_uniform_name_buffer != DE_NULL)
   5961 	{
   5962 		delete[] m_uniform_name_buffer;
   5963 
   5964 		m_uniform_name_buffer = DE_NULL;
   5965 	}
   5966 
   5967 	if (m_vs_id != 0)
   5968 	{
   5969 		gl.deleteShader(m_vs_id);
   5970 
   5971 		m_vs_id = 0;
   5972 	}
   5973 }
   5974 
   5975 /** Generates double-precision values for all uniforms defined for all program objects
   5976  *  used by the test.
   5977  *
   5978  *  This function DOES NOT use any GL API. It only calculates & stores the values
   5979  *  in internal storage for further usage.
   5980  */
   5981 void GPUShaderFP64Test4::generateUniformValues()
   5982 {
   5983 	_stage_data*	   stages[] = { &m_data_cs, &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
   5984 	const unsigned int n_stages = sizeof(stages) / sizeof(stages[0]);
   5985 
   5986 	for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
   5987 	{
   5988 		_stage_data* stage_ptr = stages[n_stage];
   5989 
   5990 		/* Iterate through all uniform components and assign them double values */
   5991 		double* double_ptrs[] = {
   5992 			&stage_ptr->uniform_structure_arrays[0].uniform_double,
   5993 			stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 0,
   5994 			stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 1,
   5995 			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 0,
   5996 			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 1,
   5997 			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 2,
   5998 			stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 3,
   5999 			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 0,
   6000 			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 1,
   6001 			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 2,
   6002 			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 3,
   6003 			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 4,
   6004 			stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 5,
   6005 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 0,
   6006 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 1,
   6007 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 2,
   6008 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 3,
   6009 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 4,
   6010 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 5,
   6011 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 6,
   6012 			stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 7,
   6013 			&stage_ptr->uniform_structure_arrays[1].uniform_double,
   6014 			stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 0,
   6015 			stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 1,
   6016 			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 0,
   6017 			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 1,
   6018 			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 2,
   6019 			stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 3,
   6020 			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 0,
   6021 			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 1,
   6022 			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 2,
   6023 			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 3,
   6024 			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 4,
   6025 			stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 5,
   6026 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 0,
   6027 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 1,
   6028 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 2,
   6029 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 3,
   6030 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 4,
   6031 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 5,
   6032 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 6,
   6033 			stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 7,
   6034 			&stage_ptr->uniforms.uniform_double,
   6035 			stage_ptr->uniforms.uniform_double_arr + 0,
   6036 			stage_ptr->uniforms.uniform_double_arr + 1,
   6037 			stage_ptr->uniforms.uniform_dvec2 + 0,
   6038 			stage_ptr->uniforms.uniform_dvec2 + 1,
   6039 			stage_ptr->uniforms.uniform_dvec2_arr + 0,
   6040 			stage_ptr->uniforms.uniform_dvec2_arr + 1,
   6041 			stage_ptr->uniforms.uniform_dvec2_arr + 2,
   6042 			stage_ptr->uniforms.uniform_dvec2_arr + 3,
   6043 			stage_ptr->uniforms.uniform_dvec3 + 0,
   6044 			stage_ptr->uniforms.uniform_dvec3 + 1,
   6045 			stage_ptr->uniforms.uniform_dvec3 + 2,
   6046 			stage_ptr->uniforms.uniform_dvec3_arr + 0,
   6047 			stage_ptr->uniforms.uniform_dvec3_arr + 1,
   6048 			stage_ptr->uniforms.uniform_dvec3_arr + 2,
   6049 			stage_ptr->uniforms.uniform_dvec3_arr + 3,
   6050 			stage_ptr->uniforms.uniform_dvec3_arr + 4,
   6051 			stage_ptr->uniforms.uniform_dvec3_arr + 5,
   6052 			stage_ptr->uniforms.uniform_dvec4 + 0,
   6053 			stage_ptr->uniforms.uniform_dvec4 + 1,
   6054 			stage_ptr->uniforms.uniform_dvec4 + 2,
   6055 			stage_ptr->uniforms.uniform_dvec4 + 3,
   6056 			stage_ptr->uniforms.uniform_dvec4_arr + 0,
   6057 			stage_ptr->uniforms.uniform_dvec4_arr + 1,
   6058 			stage_ptr->uniforms.uniform_dvec4_arr + 2,
   6059 			stage_ptr->uniforms.uniform_dvec4_arr + 3,
   6060 			stage_ptr->uniforms.uniform_dvec4_arr + 4,
   6061 			stage_ptr->uniforms.uniform_dvec4_arr + 5,
   6062 			stage_ptr->uniforms.uniform_dvec4_arr + 6,
   6063 			stage_ptr->uniforms.uniform_dvec4_arr + 7,
   6064 		};
   6065 		const unsigned int n_double_ptrs = sizeof(double_ptrs) / sizeof(double_ptrs[0]);
   6066 
   6067 		for (unsigned int n_double_ptr = 0; n_double_ptr < n_double_ptrs; ++n_double_ptr)
   6068 		{
   6069 			double* double_ptr = double_ptrs[n_double_ptr];
   6070 
   6071 			/* Generate the value. Use magic numbers to generate a set of double-precision
   6072 			 * floating-point numbers.
   6073 			 */
   6074 			static int seed = 16762362;
   6075 
   6076 			*double_ptr = ((double)(seed % 1732)) / 125.7 * (((seed % 2) == 0) ? 1 : -1);
   6077 
   6078 			seed += 751;
   6079 		} /* for (all pointers to double variables) */
   6080 	}	 /* for (all stages) */
   6081 }
   6082 
   6083 /** Initializes all program & shader objects required to run the test. The function also
   6084  *  retrieves locations of all uniforms defined by both program objects.
   6085  **/
   6086 void GPUShaderFP64Test4::initProgramObjects()
   6087 {
   6088 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6089 
   6090 	/* Create program & shader objects */
   6091 
   6092 	/* Compute shader support and GL 4.2 required */
   6093 	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
   6094 		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
   6095 	{
   6096 		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
   6097 	}
   6098 
   6099 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
   6100 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
   6101 	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
   6102 	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
   6103 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   6104 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
   6105 
   6106 	/* m_cs_id is initialized only if compute shaders are supported */
   6107 	if (0 != m_cs_id)
   6108 	{
   6109 		m_po_cs_id = gl.createProgram();
   6110 	}
   6111 
   6112 	m_po_noncs_id = gl.createProgram();
   6113 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
   6114 
   6115 	/* Configure compute shader body */
   6116 	const char* cs_body = "#version 420\n"
   6117 						  "#extension GL_ARB_compute_shader          : require\n"
   6118 						  "\n"
   6119 						  "layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n"
   6120 						  "\n"
   6121 						  "layout(rgba32f) uniform image2D testImage;\n"
   6122 						  "\n"
   6123 						  "uniform double cs_double;\n"
   6124 						  "uniform dvec2  cs_dvec2;\n"
   6125 						  "uniform dvec3  cs_dvec3;\n"
   6126 						  "uniform dvec4  cs_dvec4;\n"
   6127 						  "uniform double cs_double_arr[2];\n"
   6128 						  "uniform dvec2  cs_dvec2_arr [2];\n"
   6129 						  "uniform dvec3  cs_dvec3_arr [2];\n"
   6130 						  "uniform dvec4  cs_dvec4_arr [2];\n"
   6131 						  "\n"
   6132 						  "uniform struct cs_struct\n"
   6133 						  "{\n"
   6134 						  "    double struct_double;\n"
   6135 						  "    dvec2  struct_dvec2;\n"
   6136 						  "    dvec3  struct_dvec3;\n"
   6137 						  "    dvec4  struct_dvec4;\n"
   6138 						  "} cs_array[2];\n"
   6139 						  "\n"
   6140 						  "void main()\n"
   6141 						  "{\n"
   6142 						  "    double tmp = cs_double                  * cs_dvec2.x                 * cs_dvec3.y       "
   6143 						  "          * cs_dvec4.z                 *\n"
   6144 						  "                 cs_double_arr[0]           * cs_dvec2_arr[0].x          * "
   6145 						  "cs_dvec3_arr[0].z          * cs_dvec4_arr[0].w          *\n"
   6146 						  "                 cs_double_arr[1]           * cs_dvec2_arr[1].x          * "
   6147 						  "cs_dvec3_arr[1].z          * cs_dvec4_arr[1].w          *\n"
   6148 						  "                 cs_array[0].struct_double  * cs_array[0].struct_dvec2.y * "
   6149 						  "cs_array[0].struct_dvec3.z * cs_array[0].struct_dvec4.w *\n"
   6150 						  "                 cs_array[1].struct_double  * cs_array[1].struct_dvec2.y * "
   6151 						  "cs_array[1].struct_dvec3.z * cs_array[1].struct_dvec4.w;\n"
   6152 						  "\n"
   6153 						  "    imageStore(testImage, ivec2(0, 0), (tmp > 1.0) ? vec4(1.0) : vec4(0.0) );\n"
   6154 						  "}\n";
   6155 
   6156 	/* m_cs_id is initialized only if compute shaders are supported */
   6157 	if (0 != m_cs_id)
   6158 	{
   6159 		gl.shaderSource(m_cs_id, 1 /* count */, &cs_body, DE_NULL /* length */);
   6160 		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   6161 	}
   6162 
   6163 	/* Configure vertex shader body */
   6164 	const char* vs_body = "#version 400\n"
   6165 						  "\n"
   6166 						  "uniform double vs_double;\n"
   6167 						  "uniform dvec2  vs_dvec2;\n"
   6168 						  "uniform dvec3  vs_dvec3;\n"
   6169 						  "uniform dvec4  vs_dvec4;\n"
   6170 						  "uniform double vs_double_arr[2];\n"
   6171 						  "uniform dvec2  vs_dvec2_arr [2];\n"
   6172 						  "uniform dvec3  vs_dvec3_arr [2];\n"
   6173 						  "uniform dvec4  vs_dvec4_arr [2];\n"
   6174 						  "\n"
   6175 						  "uniform struct vs_struct\n"
   6176 						  "{\n"
   6177 						  "    double struct_double;\n"
   6178 						  "    dvec2  struct_dvec2;\n"
   6179 						  "    dvec3  struct_dvec3;\n"
   6180 						  "    dvec4  struct_dvec4;\n"
   6181 						  "} vs_array[2];\n"
   6182 						  "\n"
   6183 						  "void main()\n"
   6184 						  "{\n"
   6185 						  "    if (vs_double                 * vs_dvec2.x                 * vs_dvec3.x                 "
   6186 						  "* vs_dvec4.x                 *\n"
   6187 						  "        vs_double_arr[0]          * vs_dvec2_arr[0].x          * vs_dvec3_arr[0].x          "
   6188 						  "* vs_dvec4_arr[0].x          *\n"
   6189 						  "        vs_double_arr[1]          * vs_dvec2_arr[1].x          * vs_dvec3_arr[1].x          "
   6190 						  "* vs_dvec4_arr[1].x          *\n"
   6191 						  "        vs_array[0].struct_double * vs_array[0].struct_dvec2.x * vs_array[0].struct_dvec3.x "
   6192 						  "* vs_array[0].struct_dvec4.x *\n"
   6193 						  "        vs_array[1].struct_double * vs_array[1].struct_dvec2.x * vs_array[1].struct_dvec3.x "
   6194 						  "* vs_array[1].struct_dvec4.x > 1.0)\n"
   6195 						  "    {\n"
   6196 						  "        gl_Position = vec4(0);\n"
   6197 						  "    }\n"
   6198 						  "    else\n"
   6199 						  "    {\n"
   6200 						  "        gl_Position = vec4(1);\n"
   6201 						  "    }\n"
   6202 						  "}\n";
   6203 
   6204 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
   6205 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   6206 
   6207 	/* Configure tessellation control shader body */
   6208 	const char* tc_body = "#version 400\n"
   6209 						  "\n"
   6210 						  "uniform double tc_double;\n"
   6211 						  "uniform dvec2  tc_dvec2;\n"
   6212 						  "uniform dvec3  tc_dvec3;\n"
   6213 						  "uniform dvec4  tc_dvec4;\n"
   6214 						  "uniform double tc_double_arr[2];\n"
   6215 						  "uniform dvec2  tc_dvec2_arr [2];\n"
   6216 						  "uniform dvec3  tc_dvec3_arr [2];\n"
   6217 						  "uniform dvec4  tc_dvec4_arr [2];\n"
   6218 						  "\n"
   6219 						  "uniform struct tc_struct\n"
   6220 						  "{\n"
   6221 						  "    double struct_double;\n"
   6222 						  "    dvec2  struct_dvec2;\n"
   6223 						  "    dvec3  struct_dvec3;\n"
   6224 						  "    dvec4  struct_dvec4;\n"
   6225 						  "} tc_array[2];\n"
   6226 						  "\n"
   6227 						  "layout(vertices = 4) out;\n"
   6228 						  "\n"
   6229 						  "void main()\n"
   6230 						  "{\n"
   6231 						  "    gl_TessLevelOuter[0] = (tc_double        > 1.0) ? 2.0 : 3.0;\n"
   6232 						  "    gl_TessLevelOuter[1] = (tc_dvec2.x       > 1.0) ? 3.0 : 4.0;\n"
   6233 						  "    gl_TessLevelOuter[2] = (tc_dvec3.x       > 1.0) ? 4.0 : 5.0;\n"
   6234 						  "    gl_TessLevelOuter[3] = (tc_dvec4.x       > 1.0) ? 5.0 : 6.0;\n"
   6235 						  "    gl_TessLevelInner[0] = (tc_double_arr[0] > 1.0) ? 6.0 : 7.0;\n"
   6236 						  "    gl_TessLevelInner[1] = (tc_double_arr[1] > 1.0) ? 7.0 : 8.0;\n"
   6237 						  "\n"
   6238 						  "    if (tc_dvec2_arr[0].y          * tc_dvec2_arr[1].y          *\n"
   6239 						  "        tc_dvec3_arr[0].z          * tc_dvec3_arr[1].z          *\n"
   6240 						  "        tc_dvec4_arr[0].z          * tc_dvec4_arr[1].z          *\n"
   6241 						  "        tc_array[0].struct_double  * tc_array[0].struct_dvec2.x * \n"
   6242 						  "        tc_array[0].struct_dvec3.y * tc_array[0].struct_dvec4.z * \n"
   6243 						  "        tc_array[1].struct_double  * tc_array[1].struct_dvec2.x * \n"
   6244 						  "        tc_array[1].struct_dvec3.y * tc_array[1].struct_dvec4.z > 0.0)\n"
   6245 						  "    {\n"
   6246 						  "        gl_TessLevelInner[1] = 3.0;\n"
   6247 						  "    }\n"
   6248 						  "}\n";
   6249 
   6250 	gl.shaderSource(m_tc_id, 1 /* count */, &tc_body, DE_NULL /* length */);
   6251 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   6252 
   6253 	/* Configure tessellation evaluation shader body */
   6254 	const char* te_body = "#version 400\n"
   6255 						  "\n"
   6256 						  "uniform double te_double;\n"
   6257 						  "uniform dvec2  te_dvec2;\n"
   6258 						  "uniform dvec3  te_dvec3;\n"
   6259 						  "uniform dvec4  te_dvec4;\n"
   6260 						  "uniform double te_double_arr[2];\n"
   6261 						  "uniform dvec2  te_dvec2_arr [2];\n"
   6262 						  "uniform dvec3  te_dvec3_arr [2];\n"
   6263 						  "uniform dvec4  te_dvec4_arr [2];\n"
   6264 						  "\n"
   6265 						  "uniform struct te_struct\n"
   6266 						  "{\n"
   6267 						  "    double struct_double;\n"
   6268 						  "    dvec2  struct_dvec2;\n"
   6269 						  "    dvec3  struct_dvec3;\n"
   6270 						  "    dvec4  struct_dvec4;\n"
   6271 						  "} te_array[2];\n"
   6272 						  "\n"
   6273 						  "layout(triangles) in;\n"
   6274 						  "\n"
   6275 						  "void main()\n"
   6276 						  "{\n"
   6277 						  "    if (te_double                 * te_dvec2.x                 * te_dvec3.x                 "
   6278 						  "* te_dvec4.x                 *\n"
   6279 						  "        te_double_arr[0]          * te_dvec2_arr[0].x          * te_dvec3_arr[0].x          "
   6280 						  "* te_dvec4_arr[0].x          *\n"
   6281 						  "        te_double_arr[1]          * te_dvec2_arr[1].x          * te_dvec3_arr[1].x          "
   6282 						  "* te_dvec4_arr[1].x          *\n"
   6283 						  "        te_array[0].struct_double * te_array[0].struct_dvec2.x * te_array[0].struct_dvec3.x "
   6284 						  "* te_array[0].struct_dvec4.x *\n"
   6285 						  "        te_array[1].struct_double * te_array[1].struct_dvec2.x * te_array[1].struct_dvec3.x "
   6286 						  "* te_array[1].struct_dvec4.x > 1.0)\n"
   6287 						  "    {\n"
   6288 						  "        gl_Position = gl_in[0].gl_Position;\n"
   6289 						  "    }\n"
   6290 						  "    else\n"
   6291 						  "    {\n"
   6292 						  "        gl_Position = gl_in[0].gl_Position + vec4(1);\n"
   6293 						  "    }\n"
   6294 						  "}\n";
   6295 
   6296 	gl.shaderSource(m_te_id, 1 /* count */, &te_body, DE_NULL /* length */);
   6297 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   6298 
   6299 	/* Configure geometry shader body */
   6300 	const char* gs_body = "#version 400\n"
   6301 						  "\n"
   6302 						  "uniform double gs_double;\n"
   6303 						  "uniform dvec2  gs_dvec2;\n"
   6304 						  "uniform dvec3  gs_dvec3;\n"
   6305 						  "uniform dvec4  gs_dvec4;\n"
   6306 						  "uniform double gs_double_arr[2];\n"
   6307 						  "uniform dvec2  gs_dvec2_arr [2];\n"
   6308 						  "uniform dvec3  gs_dvec3_arr [2];\n"
   6309 						  "uniform dvec4  gs_dvec4_arr [2];\n"
   6310 						  "\n"
   6311 						  "uniform struct gs_struct\n"
   6312 						  "{\n"
   6313 						  "    double struct_double;\n"
   6314 						  "    dvec2  struct_dvec2;\n"
   6315 						  "    dvec3  struct_dvec3;\n"
   6316 						  "    dvec4  struct_dvec4;\n"
   6317 						  "} gs_array[2];\n"
   6318 						  "\n"
   6319 						  "layout (points)                   in;\n"
   6320 						  "layout (points, max_vertices = 1) out;\n"
   6321 						  "\n"
   6322 						  "void main()\n"
   6323 						  "{\n"
   6324 						  "    if (gs_double                 * gs_dvec2.x                 * gs_dvec3.x                 "
   6325 						  "* gs_dvec4.x        *\n"
   6326 						  "        gs_double_arr[0]          * gs_dvec2_arr[0].x          * gs_dvec3_arr[0].x          "
   6327 						  "* gs_dvec4_arr[0].x *\n"
   6328 						  "        gs_double_arr[1]          * gs_dvec2_arr[1].x          * gs_dvec3_arr[1].x          "
   6329 						  "* gs_dvec4_arr[1].x *\n"
   6330 						  "        gs_array[0].struct_double * gs_array[0].struct_dvec2.x * gs_array[0].struct_dvec3.x "
   6331 						  "* gs_array[0].struct_dvec4.x *\n"
   6332 						  "        gs_array[1].struct_double * gs_array[1].struct_dvec2.x * gs_array[1].struct_dvec3.x "
   6333 						  "* gs_array[1].struct_dvec4.x > 1.0)\n"
   6334 						  "    {\n"
   6335 						  "        gl_Position = gl_in[0].gl_Position;\n"
   6336 						  "    }\n"
   6337 						  "    else\n"
   6338 						  "    {\n"
   6339 						  "        gl_Position = gl_in[0].gl_Position + vec4(1);\n"
   6340 						  "    }\n"
   6341 						  "\n"
   6342 						  "    EmitVertex();\n"
   6343 						  "}\n";
   6344 
   6345 	gl.shaderSource(m_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */);
   6346 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   6347 
   6348 	/* Configure fragment shader body */
   6349 	const char* fs_body = "#version 400\n"
   6350 						  "\n"
   6351 						  "uniform double fs_double;\n"
   6352 						  "uniform dvec2  fs_dvec2;\n"
   6353 						  "uniform dvec3  fs_dvec3;\n"
   6354 						  "uniform dvec4  fs_dvec4;\n"
   6355 						  "uniform double fs_double_arr[2];\n"
   6356 						  "uniform dvec2  fs_dvec2_arr [2];\n"
   6357 						  "uniform dvec3  fs_dvec3_arr [2];\n"
   6358 						  "uniform dvec4  fs_dvec4_arr [2];\n"
   6359 						  "\n"
   6360 						  "uniform struct fs_struct\n"
   6361 						  "{\n"
   6362 						  "    double struct_double;\n"
   6363 						  "    dvec2  struct_dvec2;\n"
   6364 						  "    dvec3  struct_dvec3;\n"
   6365 						  "    dvec4  struct_dvec4;\n"
   6366 						  "} fs_array[2];\n"
   6367 						  "\n"
   6368 						  "out vec4 result;\n"
   6369 						  "\n"
   6370 						  "void main()\n"
   6371 						  "{\n"
   6372 						  "    if (fs_double                 * fs_dvec2.x                 * fs_dvec3.x                 "
   6373 						  "* fs_dvec4.x        *\n"
   6374 						  "        fs_double_arr[0]          * fs_dvec2_arr[0].x          * fs_dvec3_arr[0].x          "
   6375 						  "* fs_dvec4_arr[0].x *\n"
   6376 						  "        fs_double_arr[1]          * fs_dvec2_arr[1].x          * fs_dvec3_arr[1].x          "
   6377 						  "* fs_dvec4_arr[1].x *\n"
   6378 						  "        fs_array[0].struct_double * fs_array[0].struct_dvec2.x * fs_array[0].struct_dvec3.x "
   6379 						  "* fs_array[0].struct_dvec4.x *\n"
   6380 						  "        fs_array[1].struct_double * fs_array[1].struct_dvec2.x * fs_array[1].struct_dvec3.x "
   6381 						  "* fs_array[1].struct_dvec4.x > 1.0)\n"
   6382 						  "    {\n"
   6383 						  "        result = vec4(0.0);\n"
   6384 						  "    }\n"
   6385 						  "    else\n"
   6386 						  "    {\n"
   6387 						  "        result = vec4(1.0);\n"
   6388 						  "    }\n"
   6389 						  "}\n";
   6390 
   6391 	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */);
   6392 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
   6393 
   6394 	/* Compile the shaders */
   6395 	const glw::GLuint  shaders[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
   6396 	const unsigned int n_shaders = sizeof(shaders) / sizeof(shaders[0]);
   6397 
   6398 	for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
   6399 	{
   6400 		glw::GLint  compile_status = GL_FALSE;
   6401 		glw::GLuint so_id		   = shaders[n_shader];
   6402 
   6403 		/* Skip compute shader if not supported */
   6404 		if (0 == so_id)
   6405 		{
   6406 			continue;
   6407 		}
   6408 
   6409 		gl.compileShader(so_id);
   6410 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
   6411 
   6412 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
   6413 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
   6414 
   6415 		if (compile_status != GL_TRUE)
   6416 		{
   6417 			TCU_FAIL("Shader compilation failed");
   6418 		}
   6419 
   6420 		if (so_id == m_cs_id)
   6421 		{
   6422 			gl.attachShader(m_po_cs_id, so_id);
   6423 		}
   6424 		else
   6425 		{
   6426 			gl.attachShader(m_po_noncs_id, so_id);
   6427 		}
   6428 
   6429 		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   6430 	} /* for (all shaders) */
   6431 
   6432 	/* Link the program */
   6433 	const glw::GLuint  programs[]  = { m_po_cs_id, m_po_noncs_id };
   6434 	const unsigned int n_programs  = sizeof(programs) / sizeof(programs[0]);
   6435 	glw::GLint		   link_status = GL_FALSE;
   6436 
   6437 	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
   6438 	{
   6439 		glw::GLuint po_id = programs[n_program];
   6440 
   6441 		/* Skip compute shader program if not supported */
   6442 		if (0 == po_id)
   6443 		{
   6444 			continue;
   6445 		}
   6446 
   6447 		gl.linkProgram(po_id);
   6448 		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   6449 
   6450 		gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
   6451 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
   6452 
   6453 		if (link_status != GL_TRUE)
   6454 		{
   6455 			TCU_FAIL("Program linking failed");
   6456 		}
   6457 	} /* for (both program objects) */
   6458 
   6459 	/* Retrieve uniform locations */
   6460 	_stage_data*			  cs_stage_data[]		= { &m_data_cs };
   6461 	static const char*		  cs_uniform_prefixes[] = { "cs_" };
   6462 	static const unsigned int n_cs_uniform_prefixes = sizeof(cs_uniform_prefixes) / sizeof(cs_uniform_prefixes[0]);
   6463 
   6464 	_stage_data*			  noncs_stage_data[]	   = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
   6465 	static const char*		  noncs_uniform_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" };
   6466 	static const unsigned int n_noncs_uniform_prefixes =
   6467 		sizeof(noncs_uniform_prefixes) / sizeof(noncs_uniform_prefixes[0]);
   6468 
   6469 	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
   6470 	{
   6471 		unsigned int  n_uniform_prefixes = DE_NULL;
   6472 		glw::GLuint   po_id				 = programs[n_program];
   6473 		_stage_data** stages_data		 = DE_NULL;
   6474 		const char**  uniform_prefixes   = DE_NULL;
   6475 
   6476 		if (n_program == 0)
   6477 		{
   6478 			stages_data		   = cs_stage_data;
   6479 			uniform_prefixes   = cs_uniform_prefixes;
   6480 			n_uniform_prefixes = n_cs_uniform_prefixes;
   6481 		}
   6482 		else
   6483 		{
   6484 			stages_data		   = noncs_stage_data;
   6485 			uniform_prefixes   = noncs_uniform_prefixes;
   6486 			n_uniform_prefixes = n_noncs_uniform_prefixes;
   6487 		}
   6488 
   6489 		/* Skip compute shader program if not supported */
   6490 		if (0 == po_id)
   6491 		{
   6492 			continue;
   6493 		}
   6494 
   6495 		/* Uniform names used by the test program consist of a prefix (different for each
   6496 		 * shader stage) and a common part.
   6497 		 */
   6498 		for (unsigned int n_uniform_prefix = 0; n_uniform_prefix < n_uniform_prefixes; ++n_uniform_prefix)
   6499 		{
   6500 			_stage_data* stage_data				  = stages_data[n_uniform_prefix];
   6501 			std::string  uniform_prefix			  = std::string(uniform_prefixes[n_uniform_prefix]);
   6502 			std::string  uniform_double_name	  = uniform_prefix + "double";
   6503 			std::string  uniform_double_arr0_name = uniform_prefix + "double_arr[0]";
   6504 			std::string  uniform_double_arr1_name = uniform_prefix + "double_arr[1]";
   6505 			std::string  uniform_dvec2_name		  = uniform_prefix + "dvec2";
   6506 			std::string  uniform_dvec2_arr0_name  = uniform_prefix + "dvec2_arr[0]";
   6507 			std::string  uniform_dvec2_arr1_name  = uniform_prefix + "dvec2_arr[1]";
   6508 			std::string  uniform_dvec3_name		  = uniform_prefix + "dvec3";
   6509 			std::string  uniform_dvec3_arr0_name  = uniform_prefix + "dvec3_arr[0]";
   6510 			std::string  uniform_dvec3_arr1_name  = uniform_prefix + "dvec3_arr[1]";
   6511 			std::string  uniform_dvec4_name		  = uniform_prefix + "dvec4";
   6512 			std::string  uniform_dvec4_arr0_name  = uniform_prefix + "dvec4_arr[0]";
   6513 			std::string  uniform_dvec4_arr1_name  = uniform_prefix + "dvec4_arr[1]";
   6514 			std::string  uniform_arr0_double_name = uniform_prefix + "array[0].struct_double";
   6515 			std::string  uniform_arr0_dvec2_name  = uniform_prefix + "array[0].struct_dvec2";
   6516 			std::string  uniform_arr0_dvec3_name  = uniform_prefix + "array[0].struct_dvec3";
   6517 			std::string  uniform_arr0_dvec4_name  = uniform_prefix + "array[0].struct_dvec4";
   6518 			std::string  uniform_arr1_double_name = uniform_prefix + "array[1].struct_double";
   6519 			std::string  uniform_arr1_dvec2_name  = uniform_prefix + "array[1].struct_dvec2";
   6520 			std::string  uniform_arr1_dvec3_name  = uniform_prefix + "array[1].struct_dvec3";
   6521 			std::string  uniform_arr1_dvec4_name  = uniform_prefix + "array[1].struct_dvec4";
   6522 
   6523 			/* Retrieve uniform locations */
   6524 			stage_data->uniforms.uniform_location_double = gl.getUniformLocation(po_id, uniform_double_name.c_str());
   6525 			stage_data->uniforms.uniform_location_double_arr[0] =
   6526 				gl.getUniformLocation(po_id, uniform_double_arr0_name.c_str());
   6527 			stage_data->uniforms.uniform_location_double_arr[1] =
   6528 				gl.getUniformLocation(po_id, uniform_double_arr1_name.c_str());
   6529 			stage_data->uniforms.uniform_location_dvec2 = gl.getUniformLocation(po_id, uniform_dvec2_name.c_str());
   6530 			stage_data->uniforms.uniform_location_dvec2_arr[0] =
   6531 				gl.getUniformLocation(po_id, uniform_dvec2_arr0_name.c_str());
   6532 			stage_data->uniforms.uniform_location_dvec2_arr[1] =
   6533 				gl.getUniformLocation(po_id, uniform_dvec2_arr1_name.c_str());
   6534 			stage_data->uniforms.uniform_location_dvec3 = gl.getUniformLocation(po_id, uniform_dvec3_name.c_str());
   6535 			stage_data->uniforms.uniform_location_dvec3_arr[0] =
   6536 				gl.getUniformLocation(po_id, uniform_dvec3_arr0_name.c_str());
   6537 			stage_data->uniforms.uniform_location_dvec3_arr[1] =
   6538 				gl.getUniformLocation(po_id, uniform_dvec3_arr1_name.c_str());
   6539 			stage_data->uniforms.uniform_location_dvec4 = gl.getUniformLocation(po_id, uniform_dvec4_name.c_str());
   6540 			stage_data->uniforms.uniform_location_dvec4_arr[0] =
   6541 				gl.getUniformLocation(po_id, uniform_dvec4_arr0_name.c_str());
   6542 			stage_data->uniforms.uniform_location_dvec4_arr[1] =
   6543 				gl.getUniformLocation(po_id, uniform_dvec4_arr1_name.c_str());
   6544 			stage_data->uniform_structure_arrays[0].uniform_location_double =
   6545 				gl.getUniformLocation(po_id, uniform_arr0_double_name.c_str());
   6546 			stage_data->uniform_structure_arrays[0].uniform_location_dvec2 =
   6547 				gl.getUniformLocation(po_id, uniform_arr0_dvec2_name.c_str());
   6548 			stage_data->uniform_structure_arrays[0].uniform_location_dvec3 =
   6549 				gl.getUniformLocation(po_id, uniform_arr0_dvec3_name.c_str());
   6550 			stage_data->uniform_structure_arrays[0].uniform_location_dvec4 =
   6551 				gl.getUniformLocation(po_id, uniform_arr0_dvec4_name.c_str());
   6552 			stage_data->uniform_structure_arrays[1].uniform_location_double =
   6553 				gl.getUniformLocation(po_id, uniform_arr1_double_name.c_str());
   6554 			stage_data->uniform_structure_arrays[1].uniform_location_dvec2 =
   6555 				gl.getUniformLocation(po_id, uniform_arr1_dvec2_name.c_str());
   6556 			stage_data->uniform_structure_arrays[1].uniform_location_dvec3 =
   6557 				gl.getUniformLocation(po_id, uniform_arr1_dvec3_name.c_str());
   6558 			stage_data->uniform_structure_arrays[1].uniform_location_dvec4 =
   6559 				gl.getUniformLocation(po_id, uniform_arr1_dvec4_name.c_str());
   6560 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");
   6561 
   6562 			if (stage_data->uniforms.uniform_location_double == -1 ||
   6563 				stage_data->uniforms.uniform_location_double_arr[0] == -1 ||
   6564 				stage_data->uniforms.uniform_location_double_arr[1] == -1 ||
   6565 				stage_data->uniforms.uniform_location_dvec2 == -1 ||
   6566 				stage_data->uniforms.uniform_location_dvec2_arr[0] == -1 ||
   6567 				stage_data->uniforms.uniform_location_dvec2_arr[1] == -1 ||
   6568 				stage_data->uniforms.uniform_location_dvec3 == -1 ||
   6569 				stage_data->uniforms.uniform_location_dvec3_arr[0] == -1 ||
   6570 				stage_data->uniforms.uniform_location_dvec3_arr[1] == -1 ||
   6571 				stage_data->uniforms.uniform_location_dvec4 == -1 ||
   6572 				stage_data->uniforms.uniform_location_dvec4_arr[0] == -1 ||
   6573 				stage_data->uniforms.uniform_location_dvec4_arr[1] == -1 ||
   6574 				stage_data->uniform_structure_arrays[0].uniform_location_double == -1 ||
   6575 				stage_data->uniform_structure_arrays[0].uniform_location_dvec2 == -1 ||
   6576 				stage_data->uniform_structure_arrays[0].uniform_location_dvec3 == -1 ||
   6577 				stage_data->uniform_structure_arrays[0].uniform_location_dvec4 == -1 ||
   6578 				stage_data->uniform_structure_arrays[1].uniform_location_double == -1 ||
   6579 				stage_data->uniform_structure_arrays[1].uniform_location_dvec2 == -1 ||
   6580 				stage_data->uniform_structure_arrays[1].uniform_location_dvec3 == -1 ||
   6581 				stage_data->uniform_structure_arrays[1].uniform_location_dvec4 == -1)
   6582 			{
   6583 				TCU_FAIL("At least one uniform is considered inactive which is invalid.");
   6584 			}
   6585 
   6586 			/* Make sure locations of subsequent items in array uniforms are correct */
   6587 			if (stage_data->uniforms.uniform_location_double_arr[1] !=
   6588 					(stage_data->uniforms.uniform_location_double_arr[0] + 1) ||
   6589 				stage_data->uniforms.uniform_location_dvec2_arr[1] !=
   6590 					(stage_data->uniforms.uniform_location_dvec2_arr[0] + 1) ||
   6591 				stage_data->uniforms.uniform_location_dvec3_arr[1] !=
   6592 					(stage_data->uniforms.uniform_location_dvec3_arr[0] + 1) ||
   6593 				stage_data->uniforms.uniform_location_dvec4_arr[1] !=
   6594 					(stage_data->uniforms.uniform_location_dvec4_arr[0] + 1))
   6595 			{
   6596 				m_testCtx.getLog() << tcu::TestLog::Message << "Uniform locations:"
   6597 															   " double_arr[0]:"
   6598 								   << stage_data->uniforms.uniform_location_double_arr[0]
   6599 								   << " double_arr[1]:" << stage_data->uniforms.uniform_location_double_arr[1]
   6600 								   << " dvec2_arr[0]:" << stage_data->uniforms.uniform_location_dvec2_arr[0]
   6601 								   << " dvec2_arr[1]:" << stage_data->uniforms.uniform_location_dvec2_arr[1]
   6602 								   << " dvec3_arr[0]:" << stage_data->uniforms.uniform_location_dvec3_arr[0]
   6603 								   << " dvec3_arr[1]:" << stage_data->uniforms.uniform_location_dvec3_arr[1]
   6604 								   << " dvec4_arr[0]:" << stage_data->uniforms.uniform_location_dvec4_arr[0]
   6605 								   << " dvec4_arr[1]:" << stage_data->uniforms.uniform_location_dvec4_arr[1]
   6606 								   << tcu::TestLog::EndMessage;
   6607 
   6608 				TCU_FAIL("Double-precision uniform array item locations are invalid.");
   6609 			}
   6610 		} /* for (all uniform prefixes) */
   6611 	}	 /* for (both program objects) */
   6612 }
   6613 
   6614 /** Initializes all objects required to run the test. */
   6615 void GPUShaderFP64Test4::initTest()
   6616 {
   6617 	initProgramObjects();
   6618 
   6619 	generateUniformValues();
   6620 	initUniformValues();
   6621 }
   6622 
   6623 /** Assigns values generated by generateUniformValues() to uniforms defined by
   6624  *  both program objects.
   6625  **/
   6626 void GPUShaderFP64Test4::initUniformValues()
   6627 {
   6628 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6629 
   6630 	/* Iterate through all programs */
   6631 	_stage_data*	   cs_stages[]	= { &m_data_cs };
   6632 	_stage_data*	   noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
   6633 	const unsigned int n_cs_stages	= sizeof(cs_stages) / sizeof(cs_stages[0]);
   6634 	const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);
   6635 
   6636 	const glw::GLuint  programs[] = { m_po_cs_id, m_po_noncs_id };
   6637 	const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
   6638 
   6639 	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
   6640 	{
   6641 		glw::GLuint   po_id		 = programs[n_program];
   6642 		unsigned int  n_stages   = 0;
   6643 		_stage_data** stage_data = DE_NULL;
   6644 
   6645 		if (po_id == m_po_cs_id)
   6646 		{
   6647 			n_stages   = n_cs_stages;
   6648 			stage_data = cs_stages;
   6649 		}
   6650 		else
   6651 		{
   6652 			n_stages   = n_noncs_stages;
   6653 			stage_data = noncs_stages;
   6654 		}
   6655 
   6656 		/* Skip compute shader program if not supported */
   6657 		if (0 == po_id)
   6658 		{
   6659 			continue;
   6660 		}
   6661 
   6662 		gl.useProgram(po_id);
   6663 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   6664 
   6665 		for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
   6666 		{
   6667 			/* Iterate through all uniforms */
   6668 			_stage_data* stage_ptr = stage_data[n_stage];
   6669 
   6670 			gl.uniform1d(stage_ptr->uniforms.uniform_location_double, stage_ptr->uniforms.uniform_double);
   6671 			gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[0], stage_ptr->uniforms.uniform_double_arr[0]);
   6672 			gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[1], stage_ptr->uniforms.uniform_double_arr[1]);
   6673 			gl.uniform1d(stage_ptr->uniform_structure_arrays[0].uniform_location_double,
   6674 						 stage_ptr->uniform_structure_arrays[0].uniform_double);
   6675 			gl.uniform1d(stage_ptr->uniform_structure_arrays[1].uniform_location_double,
   6676 						 stage_ptr->uniform_structure_arrays[1].uniform_double);
   6677 			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform1d() call(s) failed.");
   6678 
   6679 			gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2, 1 /* count */, stage_ptr->uniforms.uniform_dvec2);
   6680 			gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[0], 1 /* count */,
   6681 						  stage_ptr->uniforms.uniform_dvec2_arr + 0);
   6682 			gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[1], 1 /* count */,
   6683 						  stage_ptr->uniforms.uniform_dvec2_arr + 2);
   6684 			gl.uniform2dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2, 1 /* count */,
   6685 						  stage_ptr->uniform_structure_arrays[0].uniform_dvec2);
   6686 			gl.uniform2dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2, 1 /* count */,
   6687 						  stage_ptr->uniform_structure_arrays[1].uniform_dvec2);
   6688 			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform2dv() call(s) failed.");
   6689 
   6690 			gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3, 1 /* count */, stage_ptr->uniforms.uniform_dvec3);
   6691 			gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[0], 1 /* count */,
   6692 						  stage_ptr->uniforms.uniform_dvec3_arr + 0);
   6693 			gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[1], 1 /* count */,
   6694 						  stage_ptr->uniforms.uniform_dvec3_arr + 3);
   6695 			gl.uniform3dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3, 1 /* count */,
   6696 						  stage_ptr->uniform_structure_arrays[0].uniform_dvec3);
   6697 			gl.uniform3dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3, 1 /* count */,
   6698 						  stage_ptr->uniform_structure_arrays[1].uniform_dvec3);
   6699 			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform3dv() call(s) failed.");
   6700 
   6701 			gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4, 1 /* count */, stage_ptr->uniforms.uniform_dvec4);
   6702 			gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[0], 1 /* count */,
   6703 						  stage_ptr->uniforms.uniform_dvec4_arr + 0);
   6704 			gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[1], 1 /* count */,
   6705 						  stage_ptr->uniforms.uniform_dvec4_arr + 4);
   6706 			gl.uniform4dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4, 1 /* count */,
   6707 						  stage_ptr->uniform_structure_arrays[0].uniform_dvec4);
   6708 			gl.uniform4dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4, 1 /* count */,
   6709 						  stage_ptr->uniform_structure_arrays[1].uniform_dvec4);
   6710 			GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform4dv() call(s) failed.");
   6711 		} /* for (all shader stages) */
   6712 	}	 /* for (both program objects) */
   6713 }
   6714 
   6715 /** Executes test iteration.
   6716  *
   6717  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   6718  */
   6719 tcu::TestNode::IterateResult GPUShaderFP64Test4::iterate()
   6720 {
   6721 	/* This test does not verify GL_ARB_gpu_shader_fp64 support on purpose */
   6722 
   6723 	/* Initialize all objects required to run the test */
   6724 	initTest();
   6725 
   6726 	/* Verify the implementation reports correct values for all stages we've configured */
   6727 	m_has_test_passed &= verifyUniformValues();
   6728 
   6729 	/* Is this also the case when "program interface query" mechanism is used? */
   6730 	if (m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query"))
   6731 	{
   6732 		m_has_test_passed &= verifyProgramInterfaceQuerySupport();
   6733 	}
   6734 
   6735 	/* We're done */
   6736 	if (m_has_test_passed)
   6737 	{
   6738 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   6739 	}
   6740 	else
   6741 	{
   6742 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   6743 	}
   6744 
   6745 	return STOP;
   6746 }
   6747 
   6748 /** Verifies that:
   6749  *
   6750  *  a) glGetProgramResourceIndex()
   6751  *  b) glGetProgramResourceiv()
   6752  *  c) glGetProgramResourceName()
   6753  *
   6754  *  functions return correct values for double-precision uniforms.
   6755  *
   6756  *  @return true if the verification was passed, false otherwise.
   6757  */
   6758 bool GPUShaderFP64Test4::verifyProgramInterfaceQuerySupport()
   6759 {
   6760 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   6761 	bool				  result = true;
   6762 
   6763 	/* Iterate through all programs */
   6764 	const char*		   cs_prefixes[]	= { "cs_" };
   6765 	_stage_data*	   cs_stages[]		= { &m_data_cs };
   6766 	const char*		   noncs_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" };
   6767 	_stage_data*	   noncs_stages[]   = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
   6768 	const unsigned int n_cs_stages		= sizeof(cs_stages) / sizeof(cs_stages[0]);
   6769 	const unsigned int n_noncs_stages   = sizeof(noncs_stages) / sizeof(noncs_stages[0]);
   6770 
   6771 	const glw::GLuint  programs[] = { m_po_cs_id, m_po_noncs_id };
   6772 	const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
   6773 
   6774 	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
   6775 	{
   6776 		glw::GLuint   po_id			 = programs[n_program];
   6777 		unsigned int  n_stages		 = 0;
   6778 		const char**  stage_prefixes = DE_NULL;
   6779 		_stage_data** stage_data	 = DE_NULL;
   6780 
   6781 		if (po_id == m_po_cs_id)
   6782 		{
   6783 			n_stages	   = n_cs_stages;
   6784 			stage_data	 = cs_stages;
   6785 			stage_prefixes = cs_prefixes;
   6786 		}
   6787 		else
   6788 		{
   6789 			n_stages	   = n_noncs_stages;
   6790 			stage_data	 = noncs_stages;
   6791 			stage_prefixes = noncs_prefixes;
   6792 		}
   6793 
   6794 		/* Skip compute shader program if not supported */
   6795 		if (0 == po_id)
   6796 		{
   6797 			continue;
   6798 		}
   6799 
   6800 		/* Determine maximum uniform name length */
   6801 		glw::GLint max_uniform_name_length = 0;
   6802 
   6803 		gl.getProgramInterfaceiv(po_id, GL_UNIFORM, GL_MAX_NAME_LENGTH, &max_uniform_name_length);
   6804 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInterfaceiv() call failed.");
   6805 
   6806 		/* Allocate a buffer we will use to hold uniform names */
   6807 		m_uniform_name_buffer = new char[max_uniform_name_length];
   6808 
   6809 		for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
   6810 		{
   6811 			/* Iterate through all uniforms */
   6812 			_stage_data* stage_ptr	= stage_data[n_stage];
   6813 			const char*  stage_prefix = stage_prefixes[n_stage];
   6814 
   6815 			/* Construct an array that will be used to run the test in an automated manner */
   6816 			_program_interface_query_test_item uniforms[] = {
   6817 				/* array size */ /* name */ /* type */ /* location */
   6818 				{ 1, "double", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double },
   6819 				{ 2, "double_arr[0]", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double_arr[0] },
   6820 				{ 1, "dvec2", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2 },
   6821 				{ 2, "dvec2_arr[0]", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2_arr[0] },
   6822 				{ 1, "dvec3", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3 },
   6823 				{ 2, "dvec3_arr[0]", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3_arr[0] },
   6824 				{ 1, "dvec4", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4 },
   6825 				{ 2, "dvec4_arr[0]", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4_arr[0] },
   6826 				{ 1, "array[0].struct_double", GL_DOUBLE,
   6827 				  stage_ptr->uniform_structure_arrays->uniform_location_double },
   6828 				{ 1, "array[0].struct_dvec2", GL_DOUBLE_VEC2,
   6829 				  stage_ptr->uniform_structure_arrays->uniform_location_dvec2 },
   6830 				{ 1, "array[0].struct_dvec3", GL_DOUBLE_VEC3,
   6831 				  stage_ptr->uniform_structure_arrays->uniform_location_dvec3 },
   6832 				{ 1, "array[0].struct_dvec4", GL_DOUBLE_VEC4,
   6833 				  stage_ptr->uniform_structure_arrays->uniform_location_dvec4 },
   6834 				{ 1, "array[1].struct_double", GL_DOUBLE,
   6835 				  stage_ptr->uniform_structure_arrays->uniform_location_double },
   6836 				{ 1, "array[1].struct_dvec2", GL_DOUBLE_VEC2,
   6837 				  stage_ptr->uniform_structure_arrays->uniform_location_dvec2 },
   6838 				{ 1, "array[1].struct_dvec3", GL_DOUBLE_VEC3,
   6839 				  stage_ptr->uniform_structure_arrays->uniform_location_dvec3 },
   6840 				{ 1, "array[1].struct_dvec4", GL_DOUBLE_VEC4,
   6841 				  stage_ptr->uniform_structure_arrays->uniform_location_dvec4 },
   6842 			};
   6843 			const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]);
   6844 
   6845 			/* Prefix the names with stage-specific string */
   6846 			for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
   6847 			{
   6848 				_program_interface_query_test_item& current_item = uniforms[n_uniform];
   6849 
   6850 				current_item.name = std::string(stage_prefix) + current_item.name;
   6851 			} /* for (all uniform descriptors) */
   6852 
   6853 			const glw::GLenum  properties[] = { GL_ARRAY_SIZE, GL_TYPE };
   6854 			const unsigned int n_properties = sizeof(properties) / sizeof(properties[0]);
   6855 
   6856 			for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
   6857 			{
   6858 				_program_interface_query_test_item& current_item		  = uniforms[n_uniform];
   6859 				glw::GLint							n_written_items		  = 0;
   6860 				glw::GLint							retrieved_array_size  = 0;
   6861 				glw::GLint							retrieved_name_length = 0;
   6862 				glw::GLenum							retrieved_type		  = GL_NONE;
   6863 				glw::GLint							temp_buffer[2]		  = { 0, GL_NONE };
   6864 
   6865 				/* Retrieve index of the iteration-specific uniform */
   6866 				glw::GLuint resource_index = gl.getProgramResourceIndex(po_id, GL_UNIFORM, current_item.name.c_str());
   6867 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() call failed.");
   6868 
   6869 				/* Make sure glGetProgramResourceName() returns correct values */
   6870 				memset(m_uniform_name_buffer, 0, max_uniform_name_length);
   6871 
   6872 				gl.getProgramResourceName(po_id, GL_UNIFORM, /* interface */
   6873 										  resource_index, max_uniform_name_length, &retrieved_name_length,
   6874 										  m_uniform_name_buffer);
   6875 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName() call failed.");
   6876 
   6877 				if (current_item.name.length() != (glw::GLuint)retrieved_name_length ||
   6878 					memcmp(m_uniform_name_buffer, current_item.name.c_str(), retrieved_name_length) != 0)
   6879 				{
   6880 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid uniform name was reported at index ["
   6881 									   << resource_index << "]"
   6882 															": expected:["
   6883 									   << current_item.name << "]"
   6884 															   ", reported:["
   6885 									   << m_uniform_name_buffer << "]" << tcu::TestLog::EndMessage;
   6886 
   6887 					result = false;
   6888 					continue;
   6889 				}
   6890 
   6891 				/* Make sure glGetProgramResourceiv() returns correct values for GL_TYPE and GL_ARRAY_SIZE queries */
   6892 				gl.getProgramResourceiv(po_id, GL_UNIFORM, /* interface */
   6893 										resource_index, n_properties, properties,
   6894 										sizeof(temp_buffer) / sizeof(temp_buffer[0]), &n_written_items, temp_buffer);
   6895 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv() call failed.");
   6896 
   6897 				if (n_written_items != n_properties)
   6898 				{
   6899 					TCU_FAIL("Invalid amount of items were reported by glGetProgramResourceiv() call.");
   6900 				}
   6901 
   6902 				/* For clarity, copy the retrieved values to separate variables */
   6903 				retrieved_array_size = temp_buffer[0];
   6904 				retrieved_type		 = temp_buffer[1];
   6905 
   6906 				/* Verify the values */
   6907 				if (retrieved_array_size != current_item.expected_array_size)
   6908 				{
   6909 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid array size reported for uniform ["
   6910 									   << current_item.name << "]"
   6911 									   << ": expected:[" << current_item.expected_array_size << "]"
   6912 																								", reported:["
   6913 									   << retrieved_array_size << "]" << tcu::TestLog::EndMessage;
   6914 
   6915 					result = false;
   6916 				}
   6917 
   6918 				if (retrieved_type != current_item.expected_type)
   6919 				{
   6920 					m_testCtx.getLog() << tcu::TestLog::Message << "Invalid type reported for uniform ["
   6921 									   << current_item.name << "]"
   6922 									   << ": expected:[" << current_item.expected_type << "]"
   6923 																						  ", reported:["
   6924 									   << retrieved_type << "]" << tcu::TestLog::EndMessage;
   6925 
   6926 					result = false;
   6927 				}
   6928 			} /* for (all uniforms) */
   6929 		}	 /* for (all shader stages) */
   6930 
   6931 		/* We're now OK to release the buffer we used to hold uniform names for
   6932 		 * the program */
   6933 		if (m_uniform_name_buffer != DE_NULL)
   6934 		{
   6935 			delete[] m_uniform_name_buffer;
   6936 
   6937 			m_uniform_name_buffer = DE_NULL;
   6938 		}
   6939 	} /* for (both program objects) */
   6940 
   6941 	return result;
   6942 }
   6943 
   6944 /** Verifies glGetUniform*() calls return correct values assigned to
   6945  *  double-precision uniforms.
   6946  *
   6947  *  @return true if all values reported by OpenGL were found to be correct,
   6948  *          false otherwise.
   6949  **/
   6950 bool GPUShaderFP64Test4::verifyUniformValues()
   6951 {
   6952 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   6953 	bool				  result = true;
   6954 
   6955 	/* Iterate through all programs */
   6956 	_stage_data*	   cs_stages[]	= { &m_data_cs };
   6957 	_stage_data*	   noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
   6958 	const unsigned int n_cs_stages	= sizeof(cs_stages) / sizeof(cs_stages[0]);
   6959 	const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);
   6960 
   6961 	const glw::GLuint programs[] = {
   6962 		m_po_noncs_id, m_po_cs_id,
   6963 	};
   6964 	const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
   6965 
   6966 	/* Set up rounding for the tests */
   6967 	deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN);
   6968 
   6969 	for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
   6970 	{
   6971 		glw::GLuint   po_id		 = programs[n_program];
   6972 		unsigned int  n_stages   = 0;
   6973 		_stage_data** stage_data = DE_NULL;
   6974 
   6975 		if (po_id == m_po_cs_id)
   6976 		{
   6977 			n_stages   = n_cs_stages;
   6978 			stage_data = cs_stages;
   6979 		}
   6980 		else
   6981 		{
   6982 			n_stages   = n_noncs_stages;
   6983 			stage_data = noncs_stages;
   6984 		}
   6985 
   6986 		/* Skip compute shader program if not supported */
   6987 		if (0 == po_id)
   6988 		{
   6989 			continue;
   6990 		}
   6991 
   6992 		for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
   6993 		{
   6994 			/* Iterate through all uniforms */
   6995 			_stage_data* stage_ptr = stage_data[n_stage];
   6996 
   6997 			/* Set up arrays that we will guide the automated testing */
   6998 			const uniform_value_pair double_uniforms[] = {
   6999 				uniform_value_pair(stage_ptr->uniforms.uniform_location_double, &stage_ptr->uniforms.uniform_double),
   7000 				uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[0],
   7001 								   stage_ptr->uniforms.uniform_double_arr + 0),
   7002 				uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[1],
   7003 								   stage_ptr->uniforms.uniform_double_arr + 1),
   7004 				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_double,
   7005 								   &stage_ptr->uniform_structure_arrays[0].uniform_double),
   7006 				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_double,
   7007 								   &stage_ptr->uniform_structure_arrays[1].uniform_double)
   7008 			};
   7009 			const uniform_value_pair dvec2_uniforms[] = {
   7010 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2, stage_ptr->uniforms.uniform_dvec2),
   7011 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[0],
   7012 								   stage_ptr->uniforms.uniform_dvec2_arr + 0),
   7013 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[1],
   7014 								   stage_ptr->uniforms.uniform_dvec2_arr + 2),
   7015 				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2,
   7016 								   stage_ptr->uniform_structure_arrays[0].uniform_dvec2),
   7017 				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2,
   7018 								   stage_ptr->uniform_structure_arrays[1].uniform_dvec2)
   7019 			};
   7020 			const uniform_value_pair dvec3_uniforms[] = {
   7021 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3, stage_ptr->uniforms.uniform_dvec3),
   7022 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[0],
   7023 								   stage_ptr->uniforms.uniform_dvec3_arr + 0),
   7024 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[1],
   7025 								   stage_ptr->uniforms.uniform_dvec3_arr + 3),
   7026 				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3,
   7027 								   stage_ptr->uniform_structure_arrays[0].uniform_dvec3),
   7028 				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3,
   7029 								   stage_ptr->uniform_structure_arrays[1].uniform_dvec3)
   7030 			};
   7031 			const uniform_value_pair dvec4_uniforms[] = {
   7032 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4, stage_ptr->uniforms.uniform_dvec4),
   7033 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[0],
   7034 								   stage_ptr->uniforms.uniform_dvec4_arr + 0),
   7035 				uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[1],
   7036 								   stage_ptr->uniforms.uniform_dvec4_arr + 4),
   7037 				uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4,
   7038 								   stage_ptr->uniform_structure_arrays[0].uniform_dvec4),
   7039 				uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4,
   7040 								   stage_ptr->uniform_structure_arrays[1].uniform_dvec4)
   7041 			};
   7042 
   7043 			/* Iterate over all uniforms and verify the values reported by the API */
   7044 			double		 returned_double_data[4];
   7045 			float		 returned_float_data[4];
   7046 			int			 returned_int_data[4];
   7047 			unsigned int returned_uint_data[4];
   7048 
   7049 			for (unsigned int n_type = 0; n_type < 4 /* double/dvec2/dvec3/dvec4 */; ++n_type)
   7050 			{
   7051 				const uniform_value_pair* current_uv_pairs  = NULL;
   7052 				const unsigned int		  n_components_used = n_type + 1; /* n_type=0: double, n_type=1: dvec2, etc.. */
   7053 				unsigned int			  n_pairs			= 0;
   7054 
   7055 				switch (n_type)
   7056 				{
   7057 				case 0: /* double */
   7058 				{
   7059 					current_uv_pairs = double_uniforms;
   7060 					n_pairs			 = sizeof(double_uniforms) / sizeof(double_uniforms[0]);
   7061 
   7062 					break;
   7063 				}
   7064 
   7065 				case 1: /* dvec2 */
   7066 				{
   7067 					current_uv_pairs = dvec2_uniforms;
   7068 					n_pairs			 = sizeof(dvec2_uniforms) / sizeof(dvec2_uniforms[0]);
   7069 
   7070 					break;
   7071 				}
   7072 
   7073 				case 2: /* dvec3 */
   7074 				{
   7075 					current_uv_pairs = dvec3_uniforms;
   7076 					n_pairs			 = sizeof(dvec3_uniforms) / sizeof(dvec3_uniforms[0]);
   7077 
   7078 					break;
   7079 				}
   7080 
   7081 				case 3: /* dvec4 */
   7082 				{
   7083 					current_uv_pairs = dvec4_uniforms;
   7084 					n_pairs			 = sizeof(dvec4_uniforms) / sizeof(dvec4_uniforms[0]);
   7085 
   7086 					break;
   7087 				}
   7088 
   7089 				default:
   7090 				{
   7091 					TCU_FAIL("Invalid type index requested");
   7092 				}
   7093 				} /* switch (n_type) */
   7094 
   7095 				for (unsigned int n_pair = 0; n_pair < n_pairs; ++n_pair)
   7096 				{
   7097 					const uniform_value_pair& current_uv_pair  = current_uv_pairs[n_pair];
   7098 					glw::GLint				  uniform_location = current_uv_pair.first;
   7099 					const double*			  uniform_value	= current_uv_pair.second;
   7100 
   7101 					/* Retrieve the values from the GL implementation*/
   7102 					gl.getUniformdv(po_id, uniform_location, returned_double_data);
   7103 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformdv() call failed.");
   7104 
   7105 					gl.getUniformfv(po_id, uniform_location, returned_float_data);
   7106 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformfv() call failed.");
   7107 
   7108 					gl.getUniformiv(po_id, uniform_location, returned_int_data);
   7109 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformiv() call failed.");
   7110 
   7111 					gl.getUniformuiv(po_id, uniform_location, returned_uint_data);
   7112 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformuiv() call failed.");
   7113 
   7114 					/* Make sure the values reported match the reference values */
   7115 					bool		can_continue = true;
   7116 					const float epsilon		 = 1e-5f;
   7117 
   7118 					for (unsigned int n_component = 0; n_component < n_components_used && can_continue; ++n_component)
   7119 					{
   7120 						if (de::abs(returned_double_data[n_component] - uniform_value[n_component]) > epsilon)
   7121 						{
   7122 							m_testCtx.getLog()
   7123 								<< tcu::TestLog::Message
   7124 								<< "Invalid uniform value reported by glGetUniformdv() for uniform location ["
   7125 								<< uniform_location << "]"
   7126 													   " and component ["
   7127 								<< n_component << "]"
   7128 												  ": retrieved:["
   7129 								<< returned_double_data[n_component] << "]"
   7130 																		", expected:["
   7131 								<< uniform_value[n_component] << "]" << tcu::TestLog::EndMessage;
   7132 
   7133 							result = false;
   7134 						}
   7135 
   7136 						if (de::abs(returned_float_data[n_component] - uniform_value[n_component]) > epsilon)
   7137 						{
   7138 							m_testCtx.getLog()
   7139 								<< tcu::TestLog::Message
   7140 								<< "Invalid uniform value reported by glGetUniformfv() for uniform location ["
   7141 								<< uniform_location << "]"
   7142 													   " and component ["
   7143 								<< n_component << "]"
   7144 												  ": retrieved:["
   7145 								<< returned_float_data[n_component] << "]"
   7146 																	   ", expected:["
   7147 								<< uniform_value[n_component] << "]" << tcu::TestLog::EndMessage;
   7148 
   7149 							result = false;
   7150 						}
   7151 
   7152 						/* ints */
   7153 						int rounded_uniform_value_sint = (int)(deFloatRound((float)uniform_value[n_component]));
   7154 						unsigned int rounded_uniform_value_uint =
   7155 							(unsigned int)(uniform_value[n_component] > 0.0) ?
   7156 								((unsigned int)deFloatRound((float)uniform_value[n_component])) :
   7157 								0;
   7158 
   7159 						if (returned_int_data[n_component] != rounded_uniform_value_sint)
   7160 						{
   7161 							m_testCtx.getLog()
   7162 								<< tcu::TestLog::Message
   7163 								<< "Invalid uniform value reported by glGetUniformiv() for uniform location ["
   7164 								<< uniform_location << "]"
   7165 													   " and component ["
   7166 								<< n_component << "]"
   7167 												  ": retrieved:["
   7168 								<< returned_int_data[n_component] << "]"
   7169 																	 ", expected:["
   7170 								<< rounded_uniform_value_sint << "]" << tcu::TestLog::EndMessage;
   7171 
   7172 							result = false;
   7173 						}
   7174 
   7175 						if (returned_uint_data[n_component] != rounded_uniform_value_uint)
   7176 						{
   7177 							m_testCtx.getLog()
   7178 								<< tcu::TestLog::Message
   7179 								<< "Invalid uniform value reported by glGetUniformuiv() for uniform location ["
   7180 								<< uniform_location << "]"
   7181 													   " and component ["
   7182 								<< n_component << "]"
   7183 												  ": retrieved:["
   7184 								<< returned_uint_data[n_component] << "]"
   7185 																	  ", expected:["
   7186 								<< rounded_uniform_value_uint << "]" << tcu::TestLog::EndMessage;
   7187 
   7188 							result = false;
   7189 						}
   7190 					} /* for (all components) */
   7191 				}	 /* for (all uniform+value pairs) */
   7192 			}		  /* for (all 4 uniform types) */
   7193 		}			  /* for (all shader stages) */
   7194 	}				  /* for (both program objects) */
   7195 
   7196 	/* All done! */
   7197 	return result;
   7198 }
   7199 
   7200 /** Constructor
   7201  *
   7202  *  @param context Rendering context.
   7203  */
   7204 GPUShaderFP64Test5::GPUShaderFP64Test5(deqp::Context& context)
   7205 	: TestCase(context, "conversions", "Verifies explicit and implicit casts involving double-precision"
   7206 									   " floating-point variables work correctly")
   7207 	, m_base_value_bo_data(DE_NULL)
   7208 	, m_base_value_bo_id(0)
   7209 	, m_has_test_passed(true)
   7210 	, m_po_base_value_attribute_location(-1)
   7211 	, m_po_id(0)
   7212 	, m_vao_id(0)
   7213 	, m_vs_id(0)
   7214 	, m_xfb_bo_id(0)
   7215 	, m_xfb_bo_size(0)
   7216 {
   7217 	/* Set up base value array (as per test spec) */
   7218 	m_base_values[0] = -25.12065f;
   7219 	m_base_values[1] = 0.0f;
   7220 	m_base_values[2] = 0.001f;
   7221 	m_base_values[3] = 1.0f;
   7222 	m_base_values[4] = 256.78901f;
   7223 
   7224 	/* Set up swizzle matrix */
   7225 	m_swizzle_matrix[0][0] = SWIZZLE_TYPE_NONE;
   7226 	m_swizzle_matrix[0][1] = SWIZZLE_TYPE_Y;
   7227 	m_swizzle_matrix[0][2] = SWIZZLE_TYPE_Z;
   7228 	m_swizzle_matrix[0][3] = SWIZZLE_TYPE_W;
   7229 	m_swizzle_matrix[1][0] = SWIZZLE_TYPE_NONE;
   7230 	m_swizzle_matrix[1][1] = SWIZZLE_TYPE_YX;
   7231 	m_swizzle_matrix[1][2] = SWIZZLE_TYPE_ZY;
   7232 	m_swizzle_matrix[1][3] = SWIZZLE_TYPE_WX;
   7233 	m_swizzle_matrix[2][0] = SWIZZLE_TYPE_NONE;
   7234 	m_swizzle_matrix[2][1] = SWIZZLE_TYPE_YXX;
   7235 	m_swizzle_matrix[2][2] = SWIZZLE_TYPE_XZY;
   7236 	m_swizzle_matrix[2][3] = SWIZZLE_TYPE_XWZY;
   7237 	m_swizzle_matrix[3][0] = SWIZZLE_TYPE_NONE;
   7238 	m_swizzle_matrix[3][1] = SWIZZLE_TYPE_YXXY;
   7239 	m_swizzle_matrix[3][2] = SWIZZLE_TYPE_XZXY;
   7240 	m_swizzle_matrix[3][3] = SWIZZLE_TYPE_XZYW;
   7241 }
   7242 
   7243 void GPUShaderFP64Test5::deinit()
   7244 {
   7245 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7246 
   7247 	if (m_base_value_bo_data != DE_NULL)
   7248 	{
   7249 		delete[] m_base_value_bo_data;
   7250 
   7251 		m_base_value_bo_data = DE_NULL;
   7252 	}
   7253 
   7254 	if (m_base_value_bo_id != 0)
   7255 	{
   7256 		gl.deleteBuffers(1, &m_base_value_bo_id);
   7257 
   7258 		m_base_value_bo_id = 0;
   7259 	}
   7260 
   7261 	if (m_vao_id != 0)
   7262 	{
   7263 		gl.deleteVertexArrays(1, &m_vao_id);
   7264 
   7265 		m_vao_id = 0;
   7266 	}
   7267 
   7268 	if (m_xfb_bo_id != 0)
   7269 	{
   7270 		gl.deleteBuffers(1, &m_xfb_bo_id);
   7271 
   7272 		m_xfb_bo_id = 0;
   7273 	}
   7274 
   7275 	/* TCU_FAIL will skip the per sub test iteration de-initialization, we need to
   7276 	 * take care of it here
   7277 	 */
   7278 	deinitInteration();
   7279 }
   7280 
   7281 /** Deinitializes all buffers and GL objects that may have been generated
   7282  *  during test execution.
   7283  **/
   7284 void GPUShaderFP64Test5::deinitInteration()
   7285 {
   7286 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7287 
   7288 	if (m_po_id != 0)
   7289 	{
   7290 		gl.deleteProgram(m_po_id);
   7291 
   7292 		m_po_id = 0;
   7293 	}
   7294 
   7295 	if (m_vs_id != 0)
   7296 	{
   7297 		gl.deleteShader(m_vs_id);
   7298 
   7299 		m_vs_id = 0;
   7300 	}
   7301 }
   7302 
   7303 /** Executes a single test case iteration using user-provided test case descriptor.
   7304  *
   7305  *  This function may throw a TestError exception if GL implementation misbehaves.
   7306  *
   7307  *  @param test_case Test case descriptor to use.
   7308  *
   7309  *  @return true if the values returned by GL implementation were found to be valid,
   7310  *          false otherwise.
   7311  **/
   7312 bool GPUShaderFP64Test5::executeIteration(const _test_case& test_case)
   7313 {
   7314 	bool result = true;
   7315 
   7316 	/* Convert the base values array to the type of input attribute we'll be using
   7317 	 * for the iteration.
   7318 	 */
   7319 	Utils::_variable_type base_value_type = Utils::getBaseVariableType(test_case.src_type);
   7320 
   7321 	if (base_value_type == Utils::VARIABLE_TYPE_BOOL)
   7322 	{
   7323 		/* bools are actually represented by ints, since bool varyings are not allowed */
   7324 		base_value_type = Utils::VARIABLE_TYPE_INT;
   7325 	}
   7326 
   7327 	const unsigned int base_value_component_size = Utils::getBaseVariableTypeComponentSize(base_value_type);
   7328 	const unsigned int n_base_values			 = sizeof(m_base_values) / sizeof(m_base_values[0]);
   7329 
   7330 	m_base_value_bo_data = new unsigned char[base_value_component_size * n_base_values];
   7331 
   7332 	unsigned char* base_value_traveller_ptr = m_base_value_bo_data;
   7333 
   7334 	for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value)
   7335 	{
   7336 		switch (base_value_type)
   7337 		{
   7338 		case Utils::VARIABLE_TYPE_DOUBLE:
   7339 			*((double*)base_value_traveller_ptr) = (double)m_base_values[n_base_value];
   7340 			break;
   7341 		case Utils::VARIABLE_TYPE_FLOAT:
   7342 			*((float*)base_value_traveller_ptr) = (float)m_base_values[n_base_value];
   7343 			break;
   7344 		case Utils::VARIABLE_TYPE_INT:
   7345 			*((int*)base_value_traveller_ptr) = (int)m_base_values[n_base_value];
   7346 			break;
   7347 		case Utils::VARIABLE_TYPE_UINT:
   7348 			*((unsigned int*)base_value_traveller_ptr) = (unsigned int)m_base_values[n_base_value];
   7349 			break;
   7350 
   7351 		default:
   7352 		{
   7353 			TCU_FAIL("Unrecognized base value type");
   7354 		}
   7355 		}
   7356 
   7357 		base_value_traveller_ptr += base_value_component_size;
   7358 	} /* for (all base values) */
   7359 
   7360 	/* Update buffer object storage with the data we've just finished preparing. */
   7361 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7362 
   7363 	gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id);
   7364 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   7365 
   7366 	gl.bufferSubData(GL_ARRAY_BUFFER, 0 /* offset */, base_value_component_size * n_base_values, m_base_value_bo_data);
   7367 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
   7368 
   7369 	/* Configure vertex attribute array corresponding to 'base_value' attribute, so that the
   7370 	 * new data is interpreted correctly.
   7371 	 */
   7372 	if (base_value_type == Utils::VARIABLE_TYPE_FLOAT)
   7373 	{
   7374 		gl.vertexAttribPointer(m_po_base_value_attribute_location, 1,							  /* size */
   7375 							   Utils::getGLDataTypeOfBaseVariableType(base_value_type), GL_FALSE, /* normalized */
   7376 							   0,																  /* stride */
   7377 							   DE_NULL);														  /* pointer */
   7378 		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");
   7379 	}
   7380 	else if (base_value_type == Utils::VARIABLE_TYPE_INT || base_value_type == Utils::VARIABLE_TYPE_UINT)
   7381 	{
   7382 		gl.vertexAttribIPointer(m_po_base_value_attribute_location, 1,						/* size */
   7383 								Utils::getGLDataTypeOfBaseVariableType(base_value_type), 0, /* stride */
   7384 								DE_NULL);													/* pointer */
   7385 		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer() call failed.");
   7386 	}
   7387 	else
   7388 	{
   7389 		DE_ASSERT(base_value_type == Utils::VARIABLE_TYPE_DOUBLE);
   7390 
   7391 		gl.vertexAttribLPointer(m_po_base_value_attribute_location, 1, /* size */
   7392 								GL_DOUBLE, 0,						   /* stride */
   7393 								DE_NULL);							   /* pointer */
   7394 		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertxAttribLPointer() call failed.");
   7395 	}
   7396 
   7397 	gl.enableVertexAttribArray(m_po_base_value_attribute_location);
   7398 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed.");
   7399 
   7400 	/* Execute the draw call */
   7401 	gl.useProgram(m_po_id);
   7402 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
   7403 
   7404 	gl.beginTransformFeedback(GL_POINTS);
   7405 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
   7406 	{
   7407 		gl.drawArrays(GL_POINTS, 0 /* first */, n_base_values);
   7408 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
   7409 	}
   7410 	gl.endTransformFeedback();
   7411 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
   7412 
   7413 	/* Map the XFB buffer object into process space */
   7414 	void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   7415 
   7416 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
   7417 	DE_ASSERT(xfb_data_ptr != NULL);
   7418 
   7419 	/* Verify the data */
   7420 	result &= verifyXFBData((const unsigned char*)xfb_data_ptr, test_case);
   7421 
   7422 	/* Unmap the XFB BO */
   7423 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   7424 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
   7425 
   7426 	/** Good to release the data buffer at this point */
   7427 	if (m_base_value_bo_data != DE_NULL)
   7428 	{
   7429 		delete[] m_base_value_bo_data;
   7430 
   7431 		m_base_value_bo_data = DE_NULL;
   7432 	}
   7433 
   7434 	/* All done */
   7435 	return result;
   7436 }
   7437 
   7438 /** Returns properties of a swizzle operator described by @param type swizzle type.
   7439  *
   7440  *  @param out_swizzle_string  Deref will be used to store a GLSL literal
   7441  *                             corresponding to the specific swizzle operator.
   7442  *                             Must not be NULL.
   7443  *  @param out_n_components    Deref will be used to store the amount of components
   7444  *                             used by the operator. Must not be NULL.
   7445  *  @param out_component_order Deref will be used to store up to 4 integer values,
   7446  *                             corresponding to component indices described by the
   7447  *                             operator for a particular position.  Must not be NULL.
   7448  **/
   7449 void GPUShaderFP64Test5::getSwizzleTypeProperties(_swizzle_type type, std::string* out_swizzle_string,
   7450 												  unsigned int* out_n_components, unsigned int* out_component_order)
   7451 {
   7452 	unsigned int result_component_order[4] = { 0 };
   7453 	unsigned int result_n_components	   = 0;
   7454 	std::string  result_swizzle_string;
   7455 
   7456 	switch (type)
   7457 	{
   7458 	case SWIZZLE_TYPE_NONE:
   7459 	{
   7460 		result_swizzle_string = "";
   7461 		result_n_components   = 0;
   7462 
   7463 		break;
   7464 	}
   7465 
   7466 	case SWIZZLE_TYPE_XWZY:
   7467 	{
   7468 		result_swizzle_string	 = "xwzy";
   7469 		result_n_components		  = 4;
   7470 		result_component_order[0] = 0;
   7471 		result_component_order[1] = 3;
   7472 		result_component_order[2] = 2;
   7473 		result_component_order[3] = 1;
   7474 
   7475 		break;
   7476 	}
   7477 
   7478 	case SWIZZLE_TYPE_XZXY:
   7479 	{
   7480 		result_swizzle_string	 = "xzxy";
   7481 		result_n_components		  = 4;
   7482 		result_component_order[0] = 0;
   7483 		result_component_order[1] = 2;
   7484 		result_component_order[2] = 0;
   7485 		result_component_order[3] = 1;
   7486 
   7487 		break;
   7488 	}
   7489 
   7490 	case SWIZZLE_TYPE_XZY:
   7491 	{
   7492 		result_swizzle_string	 = "xzy";
   7493 		result_n_components		  = 3;
   7494 		result_component_order[0] = 0;
   7495 		result_component_order[1] = 2;
   7496 		result_component_order[2] = 1;
   7497 
   7498 		break;
   7499 	}
   7500 
   7501 	case SWIZZLE_TYPE_XZYW:
   7502 	{
   7503 		result_swizzle_string	 = "xzyw";
   7504 		result_n_components		  = 4;
   7505 		result_component_order[0] = 0;
   7506 		result_component_order[1] = 2;
   7507 		result_component_order[2] = 1;
   7508 		result_component_order[3] = 3;
   7509 
   7510 		break;
   7511 	}
   7512 
   7513 	case SWIZZLE_TYPE_Y:
   7514 	{
   7515 		result_swizzle_string	 = "y";
   7516 		result_n_components		  = 1;
   7517 		result_component_order[0] = 1;
   7518 
   7519 		break;
   7520 	}
   7521 
   7522 	case SWIZZLE_TYPE_YX:
   7523 	{
   7524 		result_swizzle_string	 = "yx";
   7525 		result_n_components		  = 2;
   7526 		result_component_order[0] = 1;
   7527 		result_component_order[1] = 0;
   7528 
   7529 		break;
   7530 	}
   7531 
   7532 	case SWIZZLE_TYPE_YXX:
   7533 	{
   7534 		result_swizzle_string	 = "yxx";
   7535 		result_n_components		  = 3;
   7536 		result_component_order[0] = 1;
   7537 		result_component_order[1] = 0;
   7538 		result_component_order[2] = 0;
   7539 
   7540 		break;
   7541 	}
   7542 
   7543 	case SWIZZLE_TYPE_YXXY:
   7544 	{
   7545 		result_swizzle_string	 = "yxxy";
   7546 		result_n_components		  = 4;
   7547 		result_component_order[0] = 1;
   7548 		result_component_order[1] = 0;
   7549 		result_component_order[2] = 0;
   7550 		result_component_order[3] = 1;
   7551 
   7552 		break;
   7553 	}
   7554 
   7555 	case SWIZZLE_TYPE_Z:
   7556 	{
   7557 		result_swizzle_string	 = "z";
   7558 		result_n_components		  = 1;
   7559 		result_component_order[0] = 2;
   7560 
   7561 		break;
   7562 	}
   7563 
   7564 	case SWIZZLE_TYPE_ZY:
   7565 	{
   7566 		result_swizzle_string	 = "zy";
   7567 		result_n_components		  = 2;
   7568 		result_component_order[0] = 2;
   7569 		result_component_order[1] = 1;
   7570 
   7571 		break;
   7572 	}
   7573 
   7574 	case SWIZZLE_TYPE_W:
   7575 	{
   7576 		result_swizzle_string	 = "w";
   7577 		result_n_components		  = 1;
   7578 		result_component_order[0] = 3;
   7579 
   7580 		break;
   7581 	}
   7582 
   7583 	case SWIZZLE_TYPE_WX:
   7584 	{
   7585 		result_swizzle_string	 = "wx";
   7586 		result_n_components		  = 2;
   7587 		result_component_order[0] = 3;
   7588 		result_component_order[1] = 0;
   7589 
   7590 		break;
   7591 	}
   7592 
   7593 	default:
   7594 	{
   7595 		TCU_FAIL("Unrecognized swizzle type");
   7596 	}
   7597 	} /* switch (type) */
   7598 
   7599 	if (out_swizzle_string != DE_NULL)
   7600 	{
   7601 		*out_swizzle_string = result_swizzle_string;
   7602 	}
   7603 
   7604 	if (out_n_components != DE_NULL)
   7605 	{
   7606 		*out_n_components = result_n_components;
   7607 	}
   7608 
   7609 	if (out_component_order != DE_NULL)
   7610 	{
   7611 		memcpy(out_component_order, result_component_order, sizeof(unsigned int) * result_n_components);
   7612 	}
   7613 }
   7614 
   7615 /** Returns body of a vertex shader that should be used for particular test case,
   7616  *  given user-specified test case descriptor.
   7617  *
   7618  *  @param test_case Descriptor to use for the query.
   7619  *
   7620  *  @return Requested data.
   7621  **/
   7622 std::string GPUShaderFP64Test5::getVertexShaderBody(const _test_case& test_case)
   7623 {
   7624 	std::stringstream  result;
   7625 	const std::string  base_type_string = Utils::getVariableTypeString(Utils::getBaseVariableType(test_case.src_type));
   7626 	const std::string  dst_type_string  = Utils::getVariableTypeString(test_case.dst_type);
   7627 	const unsigned int n_dst_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type);
   7628 	const unsigned int n_src_components = Utils::getNumberOfComponentsForVariableType(test_case.src_type);
   7629 	const std::string  src_type_string  = Utils::getVariableTypeString(test_case.src_type);
   7630 
   7631 	/* Add version preamble */
   7632 	result << "#version 420\n"
   7633 			  "\n";
   7634 
   7635 	/* Declare output variables. Note that boolean output variables are not supported, so we need
   7636 	 * to handle that special case correctly */
   7637 	if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL)
   7638 	{
   7639 		result << "out int result;\n";
   7640 	}
   7641 	else
   7642 	{
   7643 		result << "out " << dst_type_string << " result;\n";
   7644 	}
   7645 
   7646 	/* Declare input variables. Handle the bool case exclusively. */
   7647 	if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL)
   7648 	{
   7649 		/* Use ints for bools. We will cast them to bool in the code later. */
   7650 		result << "in int base_value;\n";
   7651 	}
   7652 	else
   7653 	{
   7654 		result << "in " << base_type_string << " base_value;\n";
   7655 	}
   7656 
   7657 	/* Declare main() and construct the value we will be casting from.
   7658 	 *
   7659 	 * Note: Addition operations on bool values cause an implicit conversion to int
   7660 	 *       which is not allowed. Hence, we skip these operations for this special
   7661 	 *       case.
   7662 	 */
   7663 	result << "void main()\n"
   7664 			  "{\n"
   7665 		   << src_type_string << " lside_value = ";
   7666 
   7667 	if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL)
   7668 	{
   7669 		result << src_type_string << "(0 != ";
   7670 	}
   7671 	else
   7672 	{
   7673 		result << src_type_string << "(";
   7674 	}
   7675 
   7676 	if (test_case.src_type != Utils::VARIABLE_TYPE_BOOL)
   7677 	{
   7678 		for (unsigned int n_component = 0; n_component < n_src_components; ++n_component)
   7679 		{
   7680 			result << "base_value + " << n_component;
   7681 
   7682 			if (n_component != (n_src_components - 1))
   7683 			{
   7684 				result << ", ";
   7685 			}
   7686 		} /* for (all components) */
   7687 	}
   7688 	else
   7689 	{
   7690 		DE_ASSERT(n_src_components == 1);
   7691 
   7692 		result << "base_value";
   7693 	}
   7694 
   7695 	result << ");\n";
   7696 
   7697 	/* Perform the casting operation. Add swizzle operator if possible. */
   7698 	if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL)
   7699 	{
   7700 		/* Handle the bool case exclusively */
   7701 		if (test_case.type == TEST_CASE_TYPE_EXPLICIT)
   7702 		{
   7703 			result << "result = (bool(lside_value) == false) ? 0 : 1";
   7704 		}
   7705 		else
   7706 		{
   7707 			result << "result = (lside_value == false) ? 0 : 1";
   7708 		}
   7709 	}
   7710 	else
   7711 	{
   7712 		if (test_case.type == TEST_CASE_TYPE_EXPLICIT)
   7713 		{
   7714 			result << "result = " << dst_type_string << "(lside_value)";
   7715 		}
   7716 		else
   7717 		{
   7718 			result << "result = lside_value";
   7719 		}
   7720 	}
   7721 
   7722 	if (n_src_components > 1 && !Utils::isMatrixVariableType(test_case.src_type))
   7723 	{
   7724 		/* Add a swizzle operator  */
   7725 		DE_ASSERT(n_dst_components > 0 && n_dst_components <= 4);
   7726 		DE_ASSERT(n_src_components > 0 && n_src_components <= 4);
   7727 
   7728 		unsigned int  swizzle_component_order[4] = { 0 };
   7729 		unsigned int  swizzle_n_components		 = 0;
   7730 		_swizzle_type swizzle_operator			 = m_swizzle_matrix[n_dst_components - 1][n_src_components - 1];
   7731 		std::string   swizzle_string;
   7732 
   7733 		getSwizzleTypeProperties(swizzle_operator, &swizzle_string, &swizzle_n_components, swizzle_component_order);
   7734 
   7735 		if (swizzle_n_components > 0)
   7736 		{
   7737 			result << "." << swizzle_string;
   7738 		}
   7739 	}
   7740 
   7741 	/* Close the shader implementation. */
   7742 	result << ";\n"
   7743 			  "}\n";
   7744 
   7745 	return result.str();
   7746 }
   7747 
   7748 /** Initializes program & shader objects needed to run the iteration, given
   7749  *  user-specified test case descriptor.
   7750  *
   7751  *  This function can throw a TestError exception if a GL error is detected
   7752  *  during execution.
   7753  *
   7754  *  @param test_case Descriptor to use for the iteration.
   7755  **/
   7756 void GPUShaderFP64Test5::initIteration(_test_case& test_case)
   7757 {
   7758 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7759 
   7760 	/* Create program & shader objects */
   7761 	m_po_id = gl.createProgram();
   7762 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
   7763 
   7764 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   7765 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
   7766 
   7767 	/* Configure shader body */
   7768 	std::string body		 = getVertexShaderBody(test_case);
   7769 	const char* body_raw_ptr = body.c_str();
   7770 
   7771 	gl.shaderSource(m_vs_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */);
   7772 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
   7773 
   7774 	/* Store it in the test case descriptor for logging purposes */
   7775 	test_case.shader_body = body;
   7776 
   7777 	/* Compile the shader */
   7778 	glw::GLint compile_status = GL_FALSE;
   7779 
   7780 	gl.compileShader(m_vs_id);
   7781 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   7782 
   7783 	gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
   7784 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   7785 
   7786 	if (compile_status != GL_TRUE)
   7787 	{
   7788 		TCU_FAIL("Shader compilation failed");
   7789 	}
   7790 
   7791 	/* Attach the shader to the program obejct */
   7792 	gl.attachShader(m_po_id, m_vs_id);
   7793 	GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
   7794 
   7795 	/* Configure XFB for the program object */
   7796 	const char* xfb_varying_name = "result";
   7797 
   7798 	gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &xfb_varying_name, GL_INTERLEAVED_ATTRIBS);
   7799 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
   7800 
   7801 	/* Link the program object */
   7802 	glw::GLint link_status = GL_FALSE;
   7803 
   7804 	gl.linkProgram(m_po_id);
   7805 	GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
   7806 
   7807 	gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
   7808 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
   7809 
   7810 	if (link_status != GL_TRUE)
   7811 	{
   7812 		TCU_FAIL("Program linking failed");
   7813 	}
   7814 
   7815 	/* Retrieve attribute locations */
   7816 	m_po_base_value_attribute_location = gl.getAttribLocation(m_po_id, "base_value");
   7817 	GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation() call failed.");
   7818 
   7819 	if (m_po_base_value_attribute_location == -1)
   7820 	{
   7821 		TCU_FAIL("'base_value' is considered an inactive attribute which is invalid.");
   7822 	}
   7823 }
   7824 
   7825 /** Initializes GL objects used by all test cases.
   7826  *
   7827  *  This function may throw a TestError exception if GL implementation reports
   7828  *  an error at any point.
   7829  **/
   7830 void GPUShaderFP64Test5::initTest()
   7831 {
   7832 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   7833 
   7834 	/* Generate buffer object IDs */
   7835 	gl.genBuffers(1, &m_base_value_bo_id);
   7836 	gl.genBuffers(1, &m_xfb_bo_id);
   7837 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
   7838 
   7839 	/* Allocate buffer object storage for 'base_value' input attribute data. All iterations
   7840 	 * will never eat up more than 1 double (as per test spec) and we will be drawing
   7841 	 * as many points in a single draw call as there are defined in m_base_values array.
   7842 	 */
   7843 	const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]);
   7844 
   7845 	gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id);
   7846 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   7847 
   7848 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(double) * n_base_values, DE_NULL /* data */, GL_STATIC_DRAW);
   7849 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   7850 
   7851 	/* Allocate buffer object storage for XFB data. For each iteratiom we will be using
   7852 	 * five base values. Each XFBed value can take up to 16 components (eg. mat4) and be
   7853 	 * of double type (eg. dmat4), so make sure a sufficient amount of space is requested.
   7854 	 */
   7855 	const unsigned int xfb_bo_size = sizeof(double) * 16 /* components */ * n_base_values;
   7856 
   7857 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
   7858 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
   7859 
   7860 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
   7861 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
   7862 
   7863 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
   7864 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
   7865 
   7866 	/* Allocate a client-side buffer to hold the data we will be mapping from XFB BO */
   7867 	m_xfb_bo_size = xfb_bo_size;
   7868 
   7869 	/* Generate a vertex array object we will need to use for the draw calls */
   7870 	gl.genVertexArrays(1, &m_vao_id);
   7871 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
   7872 
   7873 	gl.bindVertexArray(m_vao_id);
   7874 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
   7875 }
   7876 
   7877 /** Executes test iteration.
   7878  *
   7879  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   7880  */
   7881 tcu::TestNode::IterateResult GPUShaderFP64Test5::iterate()
   7882 {
   7883 	/* Do not execute the test if GL_ARB_texture_view is not supported */
   7884 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
   7885 	{
   7886 		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
   7887 	}
   7888 
   7889 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit"))
   7890 	{
   7891 		throw tcu::NotSupportedError("GL_ARB_vertex_attrib_64bit is not supported.");
   7892 	}
   7893 
   7894 	/* Initialize GL objects needed to run the tests */
   7895 	initTest();
   7896 
   7897 	/* Build iteration array to run the tests in an automated manner */
   7898 	_test_case test_cases[] = {
   7899 		/* test case type */ /* source type */ /* destination type */
   7900 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" },
   7901 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
   7902 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
   7903 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
   7904 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" },
   7905 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
   7906 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
   7907 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
   7908 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" },
   7909 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
   7910 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
   7911 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
   7912 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, "" },
   7913 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, "" },
   7914 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, "" },
   7915 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, "" },
   7916 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, "" },
   7917 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, "" },
   7918 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, "" },
   7919 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, "" },
   7920 		{ TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, "" },
   7921 
   7922 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" },
   7923 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" },
   7924 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" },
   7925 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_INT, "" },
   7926 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_UINT, "" },
   7927 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_FLOAT, "" },
   7928 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_BOOL, "" },
   7929 		{ TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_BOOL, Utils::VARIABLE_TYPE_DOUBLE, "" }
   7930 	};
   7931 	const unsigned int n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
   7932 
   7933 	/* Execute all iterations */
   7934 	for (unsigned int n_test_case = 0; n_test_case < n_test_cases; ++n_test_case)
   7935 	{
   7936 		_test_case& test_case = test_cases[n_test_case];
   7937 
   7938 		/* Initialize a program object we will use to perform the casting */
   7939 		initIteration(test_case);
   7940 
   7941 		/* Use the program object to XFB the results */
   7942 		m_has_test_passed &= executeIteration(test_case);
   7943 
   7944 		/* Release the GL Resource for this sub test */
   7945 		deinitInteration();
   7946 
   7947 	} /* for (all test cases) */
   7948 	/* We're done */
   7949 	if (m_has_test_passed)
   7950 	{
   7951 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   7952 	}
   7953 	else
   7954 	{
   7955 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   7956 	}
   7957 
   7958 	return STOP;
   7959 }
   7960 
   7961 /** Verifies if data XFBed out by the vertex shader are valid, given test case descriptor,
   7962  *  for which the data have been generated.
   7963  *
   7964  *  @param data_ptr  Buffer holding the data XFBed out by the shader.
   7965  *  @param test_case Descriptor of the test case, for which the vertex shader was
   7966  *                   generated.
   7967  *
   7968  *  @return true if the data were found to be valid, false otherwise.
   7969  **/
   7970 bool GPUShaderFP64Test5::verifyXFBData(const unsigned char* data_ptr, const _test_case& test_case)
   7971 {
   7972 	const Utils::_variable_type base_dst_type		= Utils::getBaseVariableType(test_case.dst_type);
   7973 	const Utils::_variable_type base_src_type		= Utils::getBaseVariableType(test_case.src_type);
   7974 	const float					epsilon				= 1e-5f;
   7975 	const unsigned int			n_base_values		= sizeof(m_base_values) / sizeof(m_base_values[0]);
   7976 	const unsigned int			n_result_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type);
   7977 	const unsigned int			n_src_components	= Utils::getNumberOfComponentsForVariableType(test_case.src_type);
   7978 	bool						result				= true;
   7979 	_swizzle_type				swizzle_operator	= SWIZZLE_TYPE_NONE;
   7980 	unsigned int				swizzle_order[4]	= { 0 };
   7981 	const unsigned char*		traveller_ptr		= data_ptr;
   7982 
   7983 	if (!Utils::isMatrixVariableType(test_case.src_type))
   7984 	{
   7985 		DE_ASSERT(n_result_components >= 1 && n_result_components <= 4);
   7986 		DE_ASSERT(n_src_components >= 1 && n_src_components <= 4);
   7987 
   7988 		swizzle_operator = m_swizzle_matrix[n_result_components - 1][n_src_components - 1];
   7989 
   7990 		getSwizzleTypeProperties(swizzle_operator, DE_NULL, /* out_swizzle_string */
   7991 								 DE_NULL,					/* out_n_components */
   7992 								 swizzle_order);
   7993 	}
   7994 
   7995 	for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value)
   7996 	{
   7997 		for (unsigned int n_result_component = 0; n_result_component < n_result_components; ++n_result_component)
   7998 		{
   7999 			unsigned int n_swizzled_component = n_result_component;
   8000 
   8001 			if (swizzle_operator != SWIZZLE_TYPE_NONE)
   8002 			{
   8003 				n_swizzled_component =
   8004 					(n_result_component / n_result_components) * n_result_component + swizzle_order[n_result_component];
   8005 			}
   8006 
   8007 			switch (base_dst_type)
   8008 			{
   8009 			case Utils::VARIABLE_TYPE_BOOL:
   8010 			case Utils::VARIABLE_TYPE_INT:
   8011 			{
   8012 				double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component);
   8013 				double expected_value	 = ref_expected_value;
   8014 				int	result_value		  = *((int*)traveller_ptr);
   8015 
   8016 				if (base_dst_type == Utils::VARIABLE_TYPE_BOOL)
   8017 				{
   8018 					if (expected_value != 0.0)
   8019 					{
   8020 						expected_value = 1.0;
   8021 					}
   8022 				}
   8023 
   8024 				if (result_value != (int)expected_value)
   8025 				{
   8026 					m_testCtx.getLog() << tcu::TestLog::Message
   8027 									   << "Invalid boolean/integer value obtained when doing an "
   8028 									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
   8029 									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
   8030 									   << "]"
   8031 										  ", component index: ["
   8032 									   << n_swizzled_component << "]"
   8033 																  ", value: ["
   8034 									   << ref_expected_value << "]"
   8035 																" to GLSL type ["
   8036 									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
   8037 																							  ", retrieved value: ["
   8038 									   << result_value << "]"
   8039 														  ", expected value: ["
   8040 									   << (int)expected_value << "]"
   8041 																 ", shader used:\n"
   8042 									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
   8043 
   8044 					result = false;
   8045 				}
   8046 
   8047 				traveller_ptr += sizeof(int);
   8048 				break;
   8049 			} /* VARIABLE_TYPE_BOOL or VARIABLE_TYPE_INT cases */
   8050 
   8051 			case Utils::VARIABLE_TYPE_DOUBLE:
   8052 			{
   8053 				double ref_expected_value = m_base_values[n_base_value] + (double)n_swizzled_component;
   8054 				double expected_value	 = ref_expected_value;
   8055 				double result_value		  = *((double*)traveller_ptr);
   8056 
   8057 				if (base_src_type == Utils::VARIABLE_TYPE_BOOL)
   8058 				{
   8059 					expected_value = ((int)expected_value != 0.0) ? 1.0 : 0.0;
   8060 				}
   8061 				else if (base_src_type == Utils::VARIABLE_TYPE_INT)
   8062 				{
   8063 					expected_value = (int)expected_value;
   8064 				}
   8065 				else if (base_src_type == Utils::VARIABLE_TYPE_UINT)
   8066 				{
   8067 					// Negative values in base values array when converted to unsigned int will be ZERO
   8068 					// Addition operations done inside the shader in such cases will operate on ZERO rather
   8069 					// than the negative value being passed.
   8070 					// Replicate the sequence of conversion and addition operations done on the
   8071 					// shader input, to calculate the expected values in XFB data in the
   8072 					// problematic cases.
   8073 					if (expected_value < 0)
   8074 					{
   8075 						expected_value = (unsigned int)m_base_values[n_base_value] + n_swizzled_component;
   8076 					}
   8077 					expected_value = (unsigned int)expected_value;
   8078 				}
   8079 
   8080 				traveller_ptr += sizeof(double);
   8081 				if (de::abs(result_value - expected_value) > epsilon)
   8082 				{
   8083 					m_testCtx.getLog() << tcu::TestLog::Message
   8084 									   << "Invalid double-precision floating-point value obtained when doing an "
   8085 									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
   8086 									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
   8087 									   << "]"
   8088 										  ", component index: ["
   8089 									   << n_swizzled_component << "]"
   8090 																  ", value: ["
   8091 									   << ref_expected_value << "]"
   8092 																" to GLSL type ["
   8093 									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
   8094 																							  ", retrieved value: ["
   8095 									   << std::setprecision(16) << result_value << "]"
   8096 																				   ", expected value: ["
   8097 									   << std::setprecision(16) << expected_value << "]"
   8098 																					 ", shader used:\n"
   8099 									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
   8100 
   8101 					result = false;
   8102 				}
   8103 
   8104 				break;
   8105 			} /* VARIABLE_TYPE_DOUBLE case */
   8106 
   8107 			case Utils::VARIABLE_TYPE_FLOAT:
   8108 			{
   8109 				float ref_expected_value = (float)m_base_values[n_base_value] + (float)n_swizzled_component;
   8110 				float expected_value	 = ref_expected_value;
   8111 				float result_value		 = *((float*)traveller_ptr);
   8112 
   8113 				if (base_src_type == Utils::VARIABLE_TYPE_BOOL)
   8114 				{
   8115 					expected_value = (expected_value != 0.0f) ? 1.0f : 0.0f;
   8116 				}
   8117 				else if (base_src_type == Utils::VARIABLE_TYPE_INT)
   8118 				{
   8119 					expected_value = (float)((int)expected_value);
   8120 				}
   8121 				else if (base_src_type == Utils::VARIABLE_TYPE_UINT)
   8122 				{
   8123 					expected_value = (float)((unsigned int)expected_value);
   8124 				}
   8125 
   8126 				traveller_ptr += sizeof(float);
   8127 				if (de::abs(result_value - expected_value) > epsilon)
   8128 				{
   8129 					m_testCtx.getLog() << tcu::TestLog::Message
   8130 									   << "Invalid single-precision floating-point value obtained when doing an "
   8131 									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
   8132 									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
   8133 									   << "]"
   8134 										  ", component index: ["
   8135 									   << n_swizzled_component << "]"
   8136 																  ", value: ["
   8137 									   << ref_expected_value << "]"
   8138 																" to GLSL type ["
   8139 									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
   8140 																							  ", retrieved value: ["
   8141 									   << std::setprecision(16) << result_value << "]"
   8142 																				   ", expected value: ["
   8143 									   << std::setprecision(16) << expected_value << "]"
   8144 																					 ", shader used:\n"
   8145 									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
   8146 
   8147 					result = false;
   8148 				}
   8149 
   8150 				break;
   8151 			} /* VARIABLE_TYPE_FLOAT case */
   8152 
   8153 			case Utils::VARIABLE_TYPE_UINT:
   8154 			{
   8155 				double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component);
   8156 				double expected_value	 = ref_expected_value;
   8157 				unsigned int result_value = *((unsigned int*)traveller_ptr);
   8158 
   8159 				traveller_ptr += sizeof(unsigned int);
   8160 				if (result_value != (unsigned int)expected_value)
   8161 				{
   8162 					if (expected_value < 0.0)
   8163 					{
   8164 						// It is undefined to convert a negative floating-point value to an uint.
   8165 						break;
   8166 					}
   8167 
   8168 					m_testCtx.getLog() << tcu::TestLog::Message
   8169 									   << "Invalid unsigned integer value obtained when doing an "
   8170 									   << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
   8171 									   << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
   8172 									   << "]"
   8173 										  ", component index: ["
   8174 									   << n_swizzled_component << "]"
   8175 																  ", value: ["
   8176 									   << ref_expected_value << "]"
   8177 																" to GLSL type ["
   8178 									   << Utils::getVariableTypeString(test_case.dst_type) << "]"
   8179 																							  ", retrieved value: ["
   8180 									   << result_value << "]"
   8181 														  ", expected value: ["
   8182 									   << (unsigned int)expected_value << "]"
   8183 																		  ", shader used:\n"
   8184 									   << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
   8185 
   8186 					result = false;
   8187 				}
   8188 
   8189 				break;
   8190 			} /* VARIABLE_TYPE_UINT case */
   8191 
   8192 			default:
   8193 			{
   8194 				TCU_FAIL("Unrecognized variable type");
   8195 			}
   8196 			} /* switch (test_case.dst_type) */
   8197 		}	 /* for (all result components) */
   8198 	}		  /* for (all base values) */
   8199 
   8200 	return result;
   8201 }
   8202 
   8203 /** Constructor
   8204  *
   8205  *  @param context Rendering context.
   8206  */
   8207 GPUShaderFP64Test6::GPUShaderFP64Test6(deqp::Context& context)
   8208 	: TestCase(context, "illegal_conversions", "Verifies that invalid casts to double-precision variables are detected "
   8209 											   "during compilation time.")
   8210 	, m_cs_id(0)
   8211 	, m_fs_id(0)
   8212 	, m_gs_id(0)
   8213 	, m_tc_id(0)
   8214 	, m_te_id(0)
   8215 	, m_vs_id(0)
   8216 	, m_has_test_passed(true)
   8217 {
   8218 }
   8219 
   8220 /** Deinitializes all buffers and GL objects that may have been generated
   8221  *  during test execution.
   8222  **/
   8223 void GPUShaderFP64Test6::deinit()
   8224 {
   8225 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8226 
   8227 	if (m_cs_id != 0)
   8228 	{
   8229 		gl.deleteShader(m_cs_id);
   8230 
   8231 		m_cs_id = 0;
   8232 	}
   8233 
   8234 	if (m_fs_id != 0)
   8235 	{
   8236 		gl.deleteShader(m_fs_id);
   8237 
   8238 		m_fs_id = 0;
   8239 	}
   8240 
   8241 	if (m_gs_id != 0)
   8242 	{
   8243 		gl.deleteShader(m_gs_id);
   8244 
   8245 		m_gs_id = 0;
   8246 	}
   8247 
   8248 	if (m_tc_id != 0)
   8249 	{
   8250 		gl.deleteShader(m_tc_id);
   8251 
   8252 		m_tc_id = 0;
   8253 	}
   8254 
   8255 	if (m_te_id != 0)
   8256 	{
   8257 		gl.deleteShader(m_te_id);
   8258 
   8259 		m_te_id = 0;
   8260 	}
   8261 
   8262 	if (m_vs_id != 0)
   8263 	{
   8264 		gl.deleteShader(m_vs_id);
   8265 
   8266 		m_vs_id = 0;
   8267 	}
   8268 }
   8269 
   8270 /** Executes a single test case.
   8271  *
   8272  *  This function can throw TestError exceptions if GL implementation reports
   8273  *  an error.
   8274  *
   8275  *  @param test_case Test case descriptor.
   8276  *
   8277  *  @return true if test case passed, false otherwise.
   8278  **/
   8279 bool GPUShaderFP64Test6::executeIteration(const _test_case& test_case)
   8280 {
   8281 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
   8282 	const glw::GLuint	 so_ids[]   = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
   8283 	const unsigned int	n_so_ids   = sizeof(so_ids) / sizeof(so_ids[0]);
   8284 	bool				  result	 = true;
   8285 	const char*			  stage_body = NULL;
   8286 	const char*			  stage_name = NULL;
   8287 
   8288 	for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
   8289 	{
   8290 		const glw::GLuint so_id = so_ids[n_so_id];
   8291 
   8292 		/* Skip compute shader if it is not supported */
   8293 		if (0 == so_id)
   8294 		{
   8295 			continue;
   8296 		}
   8297 
   8298 		/* Compile the shader */
   8299 		gl.compileShader(so_id);
   8300 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
   8301 
   8302 		/* Has the compilation failed as expected? */
   8303 		glw::GLint compile_status = GL_TRUE;
   8304 
   8305 		gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
   8306 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
   8307 
   8308 		if (compile_status == GL_TRUE)
   8309 		{
   8310 			/* What is the current stage's name? */
   8311 			if (so_id == m_cs_id)
   8312 			{
   8313 				stage_body = test_case.cs_shader_body.c_str();
   8314 				stage_name = "Compute shader";
   8315 			}
   8316 			else if (so_id == m_fs_id)
   8317 			{
   8318 				stage_body = test_case.fs_shader_body.c_str();
   8319 				stage_name = "Fragment shader";
   8320 			}
   8321 			else if (so_id == m_gs_id)
   8322 			{
   8323 				stage_body = test_case.gs_shader_body.c_str();
   8324 				stage_name = "Geometry shader";
   8325 			}
   8326 			else if (so_id == m_tc_id)
   8327 			{
   8328 				stage_body = test_case.tc_shader_body.c_str();
   8329 				stage_name = "Tessellation control shader";
   8330 			}
   8331 			else if (so_id == m_te_id)
   8332 			{
   8333 				stage_body = test_case.te_shader_body.c_str();
   8334 				stage_name = "Tessellation evaluation shader";
   8335 			}
   8336 			else if (so_id == m_vs_id)
   8337 			{
   8338 				stage_body = test_case.vs_shader_body.c_str();
   8339 				stage_name = "Vertex shader";
   8340 			}
   8341 			else
   8342 			{
   8343 				/* Doesn't make much sense to throw exceptions here so.. */
   8344 				stage_body = "";
   8345 				stage_name = "[?]";
   8346 			}
   8347 
   8348 			/* This shader should have never compiled successfully! */
   8349 			m_testCtx.getLog() << tcu::TestLog::Message << stage_name
   8350 							   << " has been compiled successfully, even though the shader was malformed."
   8351 								  " Following is shader body:\n"
   8352 							   << stage_body << tcu::TestLog::EndMessage;
   8353 
   8354 			result = false;
   8355 		}
   8356 	} /* for (all shader objects) */
   8357 
   8358 	return result;
   8359 }
   8360 
   8361 /** Retrieves body of a compute shader that should be used for the purpose of
   8362  *  user-specified test case.
   8363  *
   8364  *  @param test_case Test case descriptor to use.
   8365  *
   8366  *  @return Requested string.
   8367  **/
   8368 std::string GPUShaderFP64Test6::getComputeShaderBody(const _test_case& test_case)
   8369 {
   8370 	std::stringstream result_sstream;
   8371 
   8372 	/* Add pre-amble */
   8373 	result_sstream << "#version 420\n"
   8374 					  "#extension GL_ARB_compute_shader          : require\n"
   8375 					  "\n"
   8376 					  "layout(local_size_x = 6) in;\n"
   8377 					  "\n"
   8378 					  "void main()\n"
   8379 					  "{\n";
   8380 
   8381 	/* Add local variable declarations */
   8382 	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
   8383 
   8384 	if (test_case.src_array_size > 1)
   8385 	{
   8386 		result_sstream << "[" << test_case.src_array_size << "]";
   8387 	}
   8388 
   8389 	result_sstream << ";\n";
   8390 
   8391 	if (test_case.wrap_dst_type_in_structure)
   8392 	{
   8393 		result_sstream << "struct\n"
   8394 						  "{\n"
   8395 					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
   8396 	}
   8397 	else
   8398 	{
   8399 		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
   8400 	}
   8401 
   8402 	result_sstream << ";\n";
   8403 
   8404 	if (test_case.wrap_dst_type_in_structure)
   8405 	{
   8406 		result_sstream << "\n} dst;\n";
   8407 	}
   8408 
   8409 	/* Add actual body */
   8410 	result_sstream << "dst = src;\n"
   8411 					  "}\n";
   8412 
   8413 	/* Return the body */
   8414 	return result_sstream.str();
   8415 }
   8416 
   8417 /** Retrieves body of a fragment shader that should be used for the purpose of
   8418  *  user-specified test case.
   8419  *
   8420  *  @param test_case Test case descriptor to use.
   8421  *
   8422  *  @return Requested string.
   8423  **/
   8424 std::string GPUShaderFP64Test6::getFragmentShaderBody(const _test_case& test_case)
   8425 {
   8426 	std::stringstream result_sstream;
   8427 
   8428 	/* Add pre-amble */
   8429 	result_sstream << "#version 420\n"
   8430 					  "\n"
   8431 					  "void main()\n"
   8432 					  "{\n";
   8433 
   8434 	/* Add local variable declarations */
   8435 	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
   8436 
   8437 	if (test_case.src_array_size > 1)
   8438 	{
   8439 		result_sstream << "[" << test_case.src_array_size << "]";
   8440 	}
   8441 
   8442 	result_sstream << ";\n";
   8443 
   8444 	if (test_case.wrap_dst_type_in_structure)
   8445 	{
   8446 		result_sstream << "struct\n"
   8447 						  "{\n"
   8448 					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
   8449 	}
   8450 	else
   8451 	{
   8452 		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
   8453 	}
   8454 
   8455 	result_sstream << ";\n";
   8456 
   8457 	if (test_case.wrap_dst_type_in_structure)
   8458 	{
   8459 		result_sstream << "\n} dst;\n";
   8460 	}
   8461 
   8462 	/* Add actual body */
   8463 	result_sstream << "dst = src;\n"
   8464 					  "}\n";
   8465 
   8466 	/* Return the body */
   8467 	return result_sstream.str();
   8468 }
   8469 
   8470 /** Retrieves body of a geometry shader that should be used for the purpose of
   8471  *  user-specified test case.
   8472  *
   8473  *  @param test_case Test case descriptor to use.
   8474  *
   8475  *  @return Requested string.
   8476  **/
   8477 std::string GPUShaderFP64Test6::getGeometryShaderBody(const _test_case& test_case)
   8478 {
   8479 	std::stringstream result_sstream;
   8480 
   8481 	/* Add preamble */
   8482 	result_sstream << "#version 420\n"
   8483 					  "\n"
   8484 					  "layout(points)                 in;\n"
   8485 					  "layout(max_vertices=1, points) out;\n"
   8486 					  "\n"
   8487 					  "void main()\n"
   8488 					  "{\n";
   8489 
   8490 	/* Add local variable declarations */
   8491 	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
   8492 
   8493 	if (test_case.src_array_size > 1)
   8494 	{
   8495 		result_sstream << "[" << test_case.src_array_size << "]";
   8496 	}
   8497 
   8498 	result_sstream << ";\n";
   8499 
   8500 	if (test_case.wrap_dst_type_in_structure)
   8501 	{
   8502 		result_sstream << "struct\n"
   8503 						  "{\n"
   8504 					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
   8505 	}
   8506 	else
   8507 	{
   8508 		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
   8509 	}
   8510 
   8511 	result_sstream << ";\n"
   8512 					  "\n";
   8513 
   8514 	if (test_case.wrap_dst_type_in_structure)
   8515 	{
   8516 		result_sstream << "} dst;\n";
   8517 	}
   8518 
   8519 	/* Add actual body */
   8520 	result_sstream << "dst = src;\n"
   8521 					  "}\n";
   8522 
   8523 	/* We're done! */
   8524 	return result_sstream.str();
   8525 }
   8526 
   8527 /** Retrieves body of a tesellation control shader that should be used for the purpose of
   8528  *  user-specified test case.
   8529  *
   8530  *  @param test_case Test case descriptor to use.
   8531  *
   8532  *  @return Requested string.
   8533  **/
   8534 std::string GPUShaderFP64Test6::getTessellationControlShaderBody(const _test_case& test_case)
   8535 {
   8536 	std::stringstream result_sstream;
   8537 
   8538 	/* Add preamble */
   8539 	result_sstream << "#version 420\n"
   8540 					  "\n"
   8541 					  "layout(vertices=4) out;\n"
   8542 					  "\n"
   8543 					  "void main()\n"
   8544 					  "{\n";
   8545 
   8546 	/* Add local variable declarations. */
   8547 	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
   8548 
   8549 	if (test_case.src_array_size > 1)
   8550 	{
   8551 		result_sstream << "[" << test_case.src_array_size << "]";
   8552 	}
   8553 
   8554 	result_sstream << ";\n";
   8555 
   8556 	if (test_case.wrap_dst_type_in_structure)
   8557 	{
   8558 		result_sstream << "struct\n"
   8559 						  "{\n"
   8560 					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
   8561 	}
   8562 	else
   8563 	{
   8564 		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
   8565 	}
   8566 
   8567 	if (test_case.wrap_dst_type_in_structure)
   8568 	{
   8569 		result_sstream << ";\n"
   8570 						  "} dst;\n";
   8571 	}
   8572 	else
   8573 	{
   8574 		result_sstream << ";\n";
   8575 	}
   8576 
   8577 	/* Continue with the actual body. */
   8578 	result_sstream << "gl_TessLevelOuter[0] = 1.0;\n"
   8579 					  "gl_TessLevelOuter[1] = 1.0;\n"
   8580 					  "dst                  = src;\n"
   8581 					  "}\n";
   8582 
   8583 	/* Return the body */
   8584 	return result_sstream.str();
   8585 }
   8586 
   8587 /** Retrieves body of a tessellation evaluation shader that should be used for the purpose of
   8588  *  user-specified test case.
   8589  *
   8590  *  @param test_case Test case descriptor to use.
   8591  *
   8592  *  @return Requested string.
   8593  **/
   8594 std::string GPUShaderFP64Test6::getTessellationEvaluationShaderBody(const _test_case& test_case)
   8595 {
   8596 	std::stringstream result_sstream;
   8597 
   8598 	/* Add preamble */
   8599 	result_sstream << "#version 420\n"
   8600 					  "\n"
   8601 					  "layout(isolines) in;\n"
   8602 					  "\n"
   8603 					  "void main()\n"
   8604 					  "{\n";
   8605 
   8606 	/* Add local variable declarations */
   8607 	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
   8608 
   8609 	if (test_case.src_array_size > 1)
   8610 	{
   8611 		result_sstream << "[" << test_case.src_array_size << "]";
   8612 	}
   8613 
   8614 	result_sstream << ";\n";
   8615 
   8616 	if (test_case.wrap_dst_type_in_structure)
   8617 	{
   8618 		result_sstream << "struct\n"
   8619 						  "{\n"
   8620 					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
   8621 	}
   8622 	else
   8623 	{
   8624 		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
   8625 	}
   8626 
   8627 	if (test_case.wrap_dst_type_in_structure)
   8628 	{
   8629 		result_sstream << ";\n"
   8630 						  "} dst;\n";
   8631 	}
   8632 	else
   8633 	{
   8634 		result_sstream << ";\n";
   8635 	}
   8636 
   8637 	/* Continue with the actual body. */
   8638 	result_sstream << "dst = src;\n";
   8639 
   8640 	/* Complete the body */
   8641 	result_sstream << "}\n";
   8642 
   8643 	/* Return the body */
   8644 	return result_sstream.str();
   8645 }
   8646 
   8647 /** Retrieves body of a vertex shader that should be used for the purpose of
   8648  *  user-specified test case.
   8649  *
   8650  *  @param test_case Test case descriptor to use.
   8651  *
   8652  *  @return Requested string.
   8653  **/
   8654 std::string GPUShaderFP64Test6::getVertexShaderBody(const _test_case& test_case)
   8655 {
   8656 	std::stringstream result_sstream;
   8657 
   8658 	/* Add preamble */
   8659 	result_sstream << "#version 420\n"
   8660 					  "\n"
   8661 					  "void main()\n"
   8662 					  "{\n";
   8663 
   8664 	/* Add local variables */
   8665 	result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
   8666 
   8667 	if (test_case.src_array_size > 1)
   8668 	{
   8669 		result_sstream << "[" << test_case.src_array_size << "]";
   8670 	}
   8671 
   8672 	result_sstream << ";\n";
   8673 
   8674 	if (test_case.wrap_dst_type_in_structure)
   8675 	{
   8676 		result_sstream << "struct\n"
   8677 						  "{\n"
   8678 					   << Utils::getVariableTypeString(test_case.dst_type) << " member";
   8679 	}
   8680 	else
   8681 	{
   8682 		result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
   8683 	}
   8684 
   8685 	if (test_case.wrap_dst_type_in_structure)
   8686 	{
   8687 		result_sstream << ";\n"
   8688 						  "} dst;\n";
   8689 	}
   8690 	else
   8691 	{
   8692 		result_sstream << ";\n";
   8693 	}
   8694 
   8695 	/* Start actual body */
   8696 	result_sstream << "dst         = src;\n"
   8697 					  "gl_Position = vec4(1.0);\n"
   8698 					  "}";
   8699 
   8700 	return result_sstream.str();
   8701 }
   8702 
   8703 /** Initializes shader objects required to run the test. */
   8704 void GPUShaderFP64Test6::initTest()
   8705 {
   8706 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8707 
   8708 	/* Generate shader objects */
   8709 
   8710 	/* Compute shader support and GL 4.2 required */
   8711 	if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
   8712 		(true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
   8713 	{
   8714 		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
   8715 	}
   8716 
   8717 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
   8718 	m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
   8719 	m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
   8720 	m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
   8721 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
   8722 
   8723 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
   8724 }
   8725 
   8726 /** Assigns shader bodies to all shader objects that will be used for a single iteration.
   8727  *
   8728  *  @param test_case Test case descriptor to generate the shader bodies for.
   8729  **/
   8730 void GPUShaderFP64Test6::initIteration(_test_case& test_case)
   8731 {
   8732 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   8733 
   8734 	test_case.cs_shader_body = getComputeShaderBody(test_case);
   8735 	test_case.fs_shader_body = getFragmentShaderBody(test_case);
   8736 	test_case.gs_shader_body = getGeometryShaderBody(test_case);
   8737 	test_case.tc_shader_body = getTessellationControlShaderBody(test_case);
   8738 	test_case.te_shader_body = getTessellationEvaluationShaderBody(test_case);
   8739 	test_case.vs_shader_body = getVertexShaderBody(test_case);
   8740 
   8741 	/* Assign the bodies to relevant shaders */
   8742 	const char* cs_body_raw_ptr = test_case.cs_shader_body.c_str();
   8743 	const char* fs_body_raw_ptr = test_case.fs_shader_body.c_str();
   8744 	const char* gs_body_raw_ptr = test_case.gs_shader_body.c_str();
   8745 	const char* tc_body_raw_ptr = test_case.tc_shader_body.c_str();
   8746 	const char* te_body_raw_ptr = test_case.te_shader_body.c_str();
   8747 	const char* vs_body_raw_ptr = test_case.vs_shader_body.c_str();
   8748 
   8749 	/* m_cs_id is initialized only if compute_shader is supported */
   8750 	if (0 != m_cs_id)
   8751 	{
   8752 		gl.shaderSource(m_cs_id, 1 /* count */, &cs_body_raw_ptr, DE_NULL /* length */);
   8753 	}
   8754 
   8755 	gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */);
   8756 	gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */);
   8757 	gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */);
   8758 	gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */);
   8759 	gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
   8760 	GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
   8761 }
   8762 
   8763 /** Executes test iteration.
   8764  *
   8765  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
   8766  */
   8767 tcu::TestNode::IterateResult GPUShaderFP64Test6::iterate()
   8768 {
   8769 	/* Do not execute the test if GL_ARB_texture_view is not supported */
   8770 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
   8771 	{
   8772 		throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
   8773 	}
   8774 
   8775 	/* Initialize GL objects needed to run the tests */
   8776 	initTest();
   8777 
   8778 	/* Build iteration array to run the tests in an automated manner */
   8779 	_test_case test_cases[] = {
   8780 		/* Src array size */ /* Src type */ /* Dst type */ /* wrap_dst_type_in_structure */
   8781 		{ 2, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
   8782 		{ 2, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
   8783 		{ 2, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
   8784 		{ 2, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
   8785 		{ 2, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
   8786 		{ 2, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
   8787 		{ 2, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
   8788 		{ 2, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
   8789 		{ 2, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
   8790 		{ 2, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
   8791 		{ 2, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
   8792 		{ 2, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
   8793 		{ 2, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
   8794 		{ 2, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
   8795 		{ 2, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
   8796 		{ 2, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
   8797 		{ 2, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
   8798 		{ 2, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
   8799 		{ 2, Utils::