Home | History | Annotate | Download | only in gl
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2015-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  gl3GPUShader5Tests.cpp
     26  * \brief Implements conformance tests for "GPU Shader 5" functionality.
     27  */ /*-------------------------------------------------------------------*/
     28 
     29 #include "gl3cGPUShader5Tests.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 <tcuMatrixUtil.hpp>
     39 #include <tcuVectorUtil.hpp>
     40 
     41 #include <cstdlib>
     42 #include <cstring>
     43 #include <limits>
     44 #include <memory>
     45 
     46 namespace gl3cts
     47 {
     48 
     49 /** Constructor
     50  *
     51  * @param context Test context
     52  **/
     53 Utils::programInfo::programInfo(deqp::Context& context)
     54 	: m_context(context), m_fragment_shader_id(0), m_program_object_id(0), m_vertex_shader_id(0)
     55 {
     56 	/* Nothing to be done here */
     57 }
     58 
     59 /** Destructor
     60  *
     61  **/
     62 Utils::programInfo::~programInfo()
     63 {
     64 	/* GL entry points */
     65 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     66 
     67 	/* Make sure program object is no longer used by GL */
     68 	gl.useProgram(0);
     69 
     70 	/* Clean program object */
     71 	if (0 != m_program_object_id)
     72 	{
     73 		gl.deleteProgram(m_program_object_id);
     74 		m_program_object_id = 0;
     75 	}
     76 
     77 	/* Clean shaders */
     78 	if (0 != m_fragment_shader_id)
     79 	{
     80 		gl.deleteShader(m_fragment_shader_id);
     81 		m_fragment_shader_id = 0;
     82 	}
     83 
     84 	if (0 != m_vertex_shader_id)
     85 	{
     86 		gl.deleteShader(m_vertex_shader_id);
     87 		m_vertex_shader_id = 0;
     88 	}
     89 }
     90 
     91 /** Build program
     92  *
     93  * @param fragment_shader_code               Fragment shader source code
     94  * @param vertex_shader_code                 Vertex shader source code
     95  * @param varying_names                      Array of strings containing names of varyings to be captured with transfrom feedback
     96  * @param n_varying_names                    Number of varyings to be captured with transfrom feedback
     97  **/
     98 void Utils::programInfo::build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code)
     99 {
    100 	/* GL entry points */
    101 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    102 
    103 	/* Create shader objects and compile */
    104 	if (0 != fragment_shader_code)
    105 	{
    106 		m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
    107 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    108 
    109 		compile(m_fragment_shader_id, fragment_shader_code);
    110 	}
    111 
    112 	if (0 != vertex_shader_code)
    113 	{
    114 		m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
    115 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
    116 
    117 		compile(m_vertex_shader_id, vertex_shader_code);
    118 	}
    119 
    120 	/* Create program object */
    121 	m_program_object_id = gl.createProgram();
    122 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
    123 
    124 	/* Link program */
    125 	link();
    126 }
    127 
    128 /** Compile shader
    129  *
    130  * @param shader_id   Shader object id
    131  * @param shader_code Shader source code
    132  **/
    133 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
    134 {
    135 	/* GL entry points */
    136 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    137 
    138 	/* Compilation status */
    139 	glw::GLint status = GL_FALSE;
    140 
    141 	/* Set source code */
    142 	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
    143 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
    144 
    145 	/* Compile */
    146 	gl.compileShader(shader_id);
    147 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
    148 
    149 	/* Get compilation status */
    150 	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
    151 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    152 
    153 	/* Log compilation error */
    154 	if (GL_TRUE != status)
    155 	{
    156 		glw::GLint				 length = 0;
    157 		std::vector<glw::GLchar> message;
    158 
    159 		/* Error log length */
    160 		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
    161 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
    162 
    163 		/* Prepare storage */
    164 		message.resize(length);
    165 
    166 		/* Get error log */
    167 		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
    168 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
    169 
    170 		/* Log */
    171 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
    172 											<< &message[0] << "\nShader source\n"
    173 											<< shader_code << tcu::TestLog::EndMessage;
    174 
    175 		TCU_FAIL("Failed to compile shader");
    176 	}
    177 }
    178 
    179 /** Attach shaders and link program
    180  *
    181  **/
    182 void Utils::programInfo::link() const
    183 {
    184 	/* GL entry points */
    185 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    186 
    187 	/* Link status */
    188 	glw::GLint status = GL_FALSE;
    189 
    190 	/* Attach shaders */
    191 	if (0 != m_fragment_shader_id)
    192 	{
    193 		gl.attachShader(m_program_object_id, m_fragment_shader_id);
    194 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    195 	}
    196 
    197 	if (0 != m_vertex_shader_id)
    198 	{
    199 		gl.attachShader(m_program_object_id, m_vertex_shader_id);
    200 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
    201 	}
    202 
    203 	/* Link */
    204 	gl.linkProgram(m_program_object_id);
    205 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
    206 
    207 	/* Get link status */
    208 	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
    209 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    210 
    211 	/* Log link error */
    212 	if (GL_TRUE != status)
    213 	{
    214 		glw::GLint				 length = 0;
    215 		std::vector<glw::GLchar> message;
    216 
    217 		/* Get error log length */
    218 		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
    219 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
    220 
    221 		message.resize(length);
    222 
    223 		/* Get error log */
    224 		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
    225 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
    226 
    227 		/* Log */
    228 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
    229 											<< &message[0] << tcu::TestLog::EndMessage;
    230 
    231 		TCU_FAIL("Failed to link program");
    232 	}
    233 }
    234 
    235 /** Set the uniform variable with provided data.
    236  *
    237  * @param type       Type of variable
    238  * @param name       Name of variable
    239  * @param data       Data
    240  */
    241 void Utils::programInfo::setUniform(Utils::_variable_type type, const glw::GLchar* name, const glw::GLvoid* data)
    242 {
    243 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    244 
    245 	const glw::GLfloat* f_data = (glw::GLfloat*)data;
    246 	const glw::GLint*   i_data = (glw::GLint*)data;
    247 	const glw::GLuint*  u_data = (glw::GLuint*)data;
    248 
    249 	/* Get location */
    250 	glw::GLint location = gl.getUniformLocation(m_program_object_id, name);
    251 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
    252 
    253 	if (-1 == location)
    254 	{
    255 		TCU_FAIL("Uniform variable is unavailable");
    256 	}
    257 
    258 	/* Set data */
    259 	switch (type)
    260 	{
    261 	case Utils::VARIABLE_TYPE_FLOAT:
    262 		gl.uniform1fv(location, 1, f_data);
    263 		break;
    264 	case Utils::VARIABLE_TYPE_INT:
    265 		gl.uniform1iv(location, 1, i_data);
    266 		break;
    267 	case Utils::VARIABLE_TYPE_IVEC2:
    268 		gl.uniform2iv(location, 1, i_data);
    269 		break;
    270 	case Utils::VARIABLE_TYPE_IVEC3:
    271 		gl.uniform3iv(location, 1, i_data);
    272 		break;
    273 	case Utils::VARIABLE_TYPE_IVEC4:
    274 		gl.uniform4iv(location, 1, i_data);
    275 		break;
    276 	case Utils::VARIABLE_TYPE_UINT:
    277 		gl.uniform1uiv(location, 1, u_data);
    278 		break;
    279 	case Utils::VARIABLE_TYPE_UVEC2:
    280 		gl.uniform2uiv(location, 1, u_data);
    281 		break;
    282 	case Utils::VARIABLE_TYPE_UVEC3:
    283 		gl.uniform3uiv(location, 1, u_data);
    284 		break;
    285 	case Utils::VARIABLE_TYPE_UVEC4:
    286 		gl.uniform4uiv(location, 1, u_data);
    287 		break;
    288 	case Utils::VARIABLE_TYPE_VEC2:
    289 		gl.uniform2fv(location, 1, f_data);
    290 		break;
    291 	case Utils::VARIABLE_TYPE_VEC3:
    292 		gl.uniform3fv(location, 1, f_data);
    293 		break;
    294 	case Utils::VARIABLE_TYPE_VEC4:
    295 		gl.uniform4fv(location, 1, f_data);
    296 		break;
    297 	default:
    298 		TCU_FAIL("Invalid enum");
    299 		break;
    300 	}
    301 
    302 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform");
    303 }
    304 
    305 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
    306  *
    307  * @param token           Token string
    308  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
    309  * @param text            String that will be used as replacement for <token>
    310  * @param string          String to work on
    311  **/
    312 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
    313 						 std::string& string)
    314 {
    315 	const size_t text_length	= strlen(text);
    316 	const size_t token_length   = strlen(token);
    317 	const size_t token_position = string.find(token, search_position);
    318 
    319 	string.replace(token_position, token_length, text, text_length);
    320 
    321 	search_position = token_position + text_length;
    322 }
    323 
    324 /* Constants used by GPUShader5ImplicitConversionsTest */
    325 const glw::GLsizei GPUShader5ImplicitConversionsTest::m_width  = 8;
    326 const glw::GLsizei GPUShader5ImplicitConversionsTest::m_height = 8;
    327 
    328 /** Constructor.
    329  *
    330  * @param context Rendering context.
    331  **/
    332 GPUShader5ImplicitConversionsTest::GPUShader5ImplicitConversionsTest(deqp::Context& context)
    333 	: TestCase(context, "implicit_conversions",
    334 			   "Verifies that implicit conversions are accepted and executed as explicit ones")
    335 	, m_fbo_id(0)
    336 	, m_tex_id(0)
    337 	, m_vao_id(0)
    338 
    339 {
    340 	/* Left blank intentionally */
    341 }
    342 
    343 /** Constructor.
    344  *
    345  * @param context     Rendering context.
    346  * @param name        Name of test
    347  * @param description Describes test
    348  **/
    349 GPUShader5ImplicitConversionsTest::GPUShader5ImplicitConversionsTest(deqp::Context& context, const char* name,
    350 																	 const char* description)
    351 	: TestCase(context, name, description), m_fbo_id(0), m_tex_id(0), m_vao_id(0)
    352 
    353 {
    354 	/* Left blank intentionally */
    355 }
    356 
    357 /** Deinitializes all GL objects that may have been created during
    358  *  test execution.
    359  **/
    360 void GPUShader5ImplicitConversionsTest::deinit()
    361 {
    362 	if (m_fbo_id != 0)
    363 	{
    364 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    365 		gl.deleteFramebuffers(1, &m_fbo_id);
    366 
    367 		m_fbo_id = 0;
    368 	}
    369 
    370 	if (m_tex_id != 0)
    371 	{
    372 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    373 		gl.deleteTextures(1, &m_tex_id);
    374 
    375 		m_tex_id = 0;
    376 	}
    377 
    378 	if (m_vao_id != 0)
    379 	{
    380 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    381 		gl.deleteVertexArrays(1, &m_vao_id);
    382 
    383 		m_vao_id = 0;
    384 	}
    385 }
    386 
    387 /** Executes test iteration.
    388  *
    389  *  @return Returns STOP.
    390  */
    391 tcu::TestNode::IterateResult GPUShader5ImplicitConversionsTest::iterate()
    392 {
    393 	/* Defines data used as u1 and u2 uniforms */
    394 	static const glw::GLint  uni_data_int_1[4]  = { 112, -1122, 111222, -1222111222 };
    395 	static const glw::GLint  uni_data_int_2[4]  = { -112, 1122, -111222, 1222111222 };
    396 	static const glw::GLuint uni_data_uint_1[4] = { 0xffff0000, 0x0000ffff, 0x00ffffff, 0xffffffff };
    397 	static const glw::GLuint uni_data_uint_2[4] = { 0xfff70000, 0x00007fff, 0x007fffff, 0xfffffff7 };
    398 
    399 	/* Defines test cases */
    400 	static const testCase test_cases[] = {
    401 		{ "uint", false, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_1, uni_data_int_2 } /* int >> uint */,
    402 		{ "uint", true, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_1, uni_data_int_1 },
    403 		{ "float", false, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_1, uni_data_int_2 } /* int >> float */,
    404 		{ "float", true, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_2, uni_data_int_2 },
    405 		{ "uvec2", false, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_2 } /* ivec2 >> uvec2 */,
    406 		{ "uvec2", true, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_1 },
    407 		{ "vec2", false, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_2 } /* ivec2 >> vec2 */,
    408 		{ "vec2", true, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_1 },
    409 		{ "uvec3", false, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_1, uni_data_int_2 } /* ivec3 >> uvec3 */,
    410 		{ "uvec3", true, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_2, uni_data_int_2 },
    411 		{ "vec3", false, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_1, uni_data_int_2 } /* ivec3 >> vec3 */,
    412 		{ "vec3", true, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_2, uni_data_int_2 },
    413 		{ "uvec4", false, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_2 } /* ivec4 >> uvec4 */,
    414 		{ "uvec4", true, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_1 },
    415 		{ "vec4", false, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_2 } /* ivec4 >> vec4 */,
    416 		{ "vec4", true, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_1 },
    417 		{ "float", false, "uint", Utils::VARIABLE_TYPE_UINT, uni_data_uint_1, uni_data_uint_2 } /* uint >> float */,
    418 		{ "float", true, "uint", Utils::VARIABLE_TYPE_UINT, uni_data_uint_2, uni_data_uint_2 },
    419 		{ "vec2", false, "uvec2", Utils::VARIABLE_TYPE_UVEC2, uni_data_uint_1, uni_data_uint_2 } /* uvec2 >> vec2 */,
    420 		{ "vec2", true, "uvec2", Utils::VARIABLE_TYPE_UVEC2, uni_data_uint_1, uni_data_uint_1 },
    421 		{ "vec3", false, "uvec3", Utils::VARIABLE_TYPE_UVEC3, uni_data_uint_1, uni_data_uint_2 } /* uvec3 >> vec3 */,
    422 		{ "vec3", true, "uvec3", Utils::VARIABLE_TYPE_UVEC3, uni_data_uint_2, uni_data_uint_2 },
    423 		{ "vec4", false, "uvec4", Utils::VARIABLE_TYPE_UVEC4, uni_data_uint_1, uni_data_uint_2 } /* uvec4 >> vec4 */,
    424 		{ "vec4", true, "uvec4", Utils::VARIABLE_TYPE_UVEC4, uni_data_uint_1, uni_data_uint_1 },
    425 	};
    426 	static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
    427 
    428 	testInit();
    429 
    430 	/* Execute test cases */
    431 	for (size_t i = 0; i < n_test_cases; ++i)
    432 	{
    433 		const testCase& test_case = test_cases[i];
    434 
    435 		executeTestCase(test_case);
    436 	}
    437 
    438 	/* Set result - exceptions are thrown in case of any error */
    439 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
    440 
    441 	/* Done */
    442 	return STOP;
    443 }
    444 
    445 /** Initializes frame buffer and vertex array
    446  *
    447  **/
    448 void GPUShader5ImplicitConversionsTest::testInit()
    449 {
    450 	/*  */
    451 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    452 
    453 	/* Prepare texture for color attachment 0 */
    454 	gl.genTextures(1, &m_tex_id);
    455 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
    456 
    457 	gl.bindTexture(GL_TEXTURE_2D, m_tex_id);
    458 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
    459 
    460 	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_width, m_height);
    461 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
    462 
    463 	/* Prepare FBO with color attachment 0 */
    464 	gl.genFramebuffers(1, &m_fbo_id);
    465 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
    466 
    467 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
    468 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
    469 
    470 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex_id, 0 /* level */);
    471 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
    472 
    473 	/* Set Viewport */
    474 	gl.viewport(0 /* x */, 0 /* y */, m_width, m_height);
    475 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
    476 
    477 	/* Prepare blank VAO */
    478 	gl.genVertexArrays(1, &m_vao_id);
    479 	GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
    480 
    481 	gl.bindVertexArray(m_vao_id);
    482 	GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
    483 }
    484 
    485 /** Verifies if image is filled with <color>
    486  *
    487  * @param color       Color to be checked
    488  * @param is_expected Selects if image is expected to be filled with given color or not
    489  **/
    490 void GPUShader5ImplicitConversionsTest::verifyImage(glw::GLuint color, bool is_expected) const
    491 {
    492 	/*  */
    493 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    494 
    495 	/* Storage for image data */
    496 	glw::GLuint result_image[m_width * m_height];
    497 
    498 	/* Get image data */
    499 	gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
    500 	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
    501 
    502 	/* Inspect data */
    503 	if (true == is_expected)
    504 	{
    505 		for (size_t i = 0; i < m_width * m_height; ++i)
    506 		{
    507 			const glw::GLuint pixel_data = result_image[i];
    508 
    509 			if (color != pixel_data)
    510 			{
    511 				TCU_FAIL("Found invalid pixel during verification of drawn image");
    512 			}
    513 		}
    514 	}
    515 	else
    516 	{
    517 		for (size_t i = 0; i < m_width * m_height; ++i)
    518 		{
    519 			const glw::GLuint pixel_data = result_image[i];
    520 
    521 			if (color == pixel_data)
    522 			{
    523 				TCU_FAIL("Found invalid pixel during verification of drawn image");
    524 			}
    525 		}
    526 	}
    527 }
    528 
    529 /** Executes test case
    530  *
    531  * @param test_case Defines test case parameters
    532  */
    533 void GPUShader5ImplicitConversionsTest::executeTestCase(const testCase& test_case)
    534 {
    535 	static const glw::GLuint white_color = 0xffffffff;
    536 
    537 	/*  */
    538 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    539 
    540 	/* Run test case */
    541 	{
    542 		/* Get shaders */
    543 		const std::string& fs = getFragmentShader();
    544 		const std::string& vs = getVertexShader(test_case.m_destination_type, test_case.m_source_type);
    545 
    546 		/* Prepare program */
    547 		Utils::programInfo program(m_context);
    548 
    549 		program.build(fs.c_str(), vs.c_str());
    550 
    551 		gl.useProgram(program.m_program_object_id);
    552 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
    553 
    554 		program.setUniform(test_case.m_source_variable_type, "u1", test_case.m_u1_data);
    555 		program.setUniform(test_case.m_source_variable_type, "u2", test_case.m_u2_data);
    556 
    557 		/* Clear FBO */
    558 		gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
    559 		GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
    560 
    561 		gl.clear(GL_COLOR_BUFFER_BIT);
    562 		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
    563 
    564 		/* Draw a triangle strip */
    565 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
    566 		GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
    567 	}
    568 
    569 	/* Verification */
    570 	verifyImage(white_color, test_case.m_is_white_expected);
    571 }
    572 
    573 /** Get vertex shader source.
    574  *
    575  * @param destination_type Name of type
    576  * @param source_type      Name of type
    577  *
    578  * @return String with source of shader
    579  */
    580 std::string GPUShader5ImplicitConversionsTest::getVertexShader(const glw::GLchar* destination_type,
    581 															   const glw::GLchar* source_type)
    582 {
    583 	/* Vertex shader template */
    584 	const char* vs_body_template = "#version 150\n"
    585 								   "#extension GL_ARB_gpu_shader5 : require\n"
    586 								   "\n"
    587 								   "uniform SOURCE_TYPE u1;\n"
    588 								   "uniform SOURCE_TYPE u2;\n"
    589 								   "\n"
    590 								   "out     vec4 result;\n"
    591 								   "\n"
    592 								   "void main()\n"
    593 								   "{\n"
    594 								   "    DESTINATION_TYPE v = ZERO;\n"
    595 								   "\n"
    596 								   "    v = DESTINATION_TYPE(u2) - u1;\n"
    597 								   "\n"
    598 								   "    result = vec4(0.0, 0.0, 0.0, 0.0);\n"
    599 								   "    if (ZERO == v)\n"
    600 								   "    {\n"
    601 								   "      result = vec4(1.0, 1.0, 1.0, 1.0);\n"
    602 								   "    }\n"
    603 								   "\n"
    604 								   "    switch (gl_VertexID)\n"
    605 								   "    {\n"
    606 								   "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
    607 								   "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
    608 								   "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
    609 								   "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
    610 								   "    }\n"
    611 								   "}\n"
    612 								   "\n";
    613 
    614 	std::string vs_body = vs_body_template;
    615 
    616 	/* Tokens */
    617 	size_t search_position = 0;
    618 
    619 	Utils::replaceToken("SOURCE_TYPE", search_position, source_type, vs_body);
    620 	Utils::replaceToken("SOURCE_TYPE", search_position, source_type, vs_body);
    621 
    622 	search_position = 0;
    623 	Utils::replaceToken("DESTINATION_TYPE", search_position, destination_type, vs_body);
    624 	Utils::replaceToken("DESTINATION_TYPE", search_position, destination_type, vs_body);
    625 
    626 	search_position = 0;
    627 	if (!strcmp(destination_type, "int") || !strcmp(destination_type, "uint"))
    628 	{
    629 		Utils::replaceToken("ZERO", search_position, "0", vs_body);
    630 		Utils::replaceToken("ZERO", search_position, "0", vs_body);
    631 	}
    632 	else if (!strcmp(destination_type, "float"))
    633 	{
    634 		Utils::replaceToken("ZERO", search_position, "0.0", vs_body);
    635 		Utils::replaceToken("ZERO", search_position, "0.0", vs_body);
    636 	}
    637 	else if (!strcmp(destination_type, "ivec2"))
    638 	{
    639 		Utils::replaceToken("ZERO", search_position, "ivec2(0,0)", vs_body);
    640 		Utils::replaceToken("ZERO", search_position, "ivec2(0,0)", vs_body);
    641 	}
    642 	else if (!strcmp(destination_type, "ivec3"))
    643 	{
    644 		Utils::replaceToken("ZERO", search_position, "ivec3(0,0,0)", vs_body);
    645 		Utils::replaceToken("ZERO", search_position, "ivec3(0,0,0)", vs_body);
    646 	}
    647 	else if (!strcmp(destination_type, "ivec4"))
    648 	{
    649 		Utils::replaceToken("ZERO", search_position, "ivec4(0,0,0,0)", vs_body);
    650 		Utils::replaceToken("ZERO", search_position, "ivec4(0,0,0,0)", vs_body);
    651 	}
    652 	else if (!strcmp(destination_type, "uvec2"))
    653 	{
    654 		Utils::replaceToken("ZERO", search_position, "uvec2(0,0)", vs_body);
    655 		Utils::replaceToken("ZERO", search_position, "uvec2(0,0)", vs_body);
    656 	}
    657 	else if (!strcmp(destination_type, "uvec3"))
    658 	{
    659 		Utils::replaceToken("ZERO", search_position, "uvec3(0,0,0)", vs_body);
    660 		Utils::replaceToken("ZERO", search_position, "uvec3(0,0,0)", vs_body);
    661 	}
    662 	else if (!strcmp(destination_type, "uvec4"))
    663 	{
    664 		Utils::replaceToken("ZERO", search_position, "uvec4(0,0,0,0)", vs_body);
    665 		Utils::replaceToken("ZERO", search_position, "uvec4(0,0,0,0)", vs_body);
    666 	}
    667 	else if (!strcmp(destination_type, "vec2"))
    668 	{
    669 		Utils::replaceToken("ZERO", search_position, "vec2(0,0)", vs_body);
    670 		Utils::replaceToken("ZERO", search_position, "vec2(0,0)", vs_body);
    671 	}
    672 	else if (!strcmp(destination_type, "vec3"))
    673 	{
    674 		Utils::replaceToken("ZERO", search_position, "vec3(0,0,0)", vs_body);
    675 		Utils::replaceToken("ZERO", search_position, "vec3(0,0,0)", vs_body);
    676 	}
    677 	else if (!strcmp(destination_type, "vec4"))
    678 	{
    679 		Utils::replaceToken("ZERO", search_position, "vec4(0,0,0,0)", vs_body);
    680 		Utils::replaceToken("ZERO", search_position, "vec4(0,0,0,0)", vs_body);
    681 	}
    682 
    683 	return vs_body;
    684 }
    685 
    686 /** Get fragment shader source.
    687  *
    688  * @return String with source of shader
    689  */
    690 std::string GPUShader5ImplicitConversionsTest::getFragmentShader()
    691 {
    692 	const char* fs_body_template = "#version 150\n"
    693 								   "\n"
    694 								   "in  vec4 result;\n"
    695 								   "out vec4 color;\n"
    696 								   "\n"
    697 								   "void main()\n"
    698 								   "{\n"
    699 								   "    color = result;\n"
    700 								   "}\n"
    701 								   "\n";
    702 
    703 	std::string fs_body = fs_body_template;
    704 
    705 	return fs_body;
    706 }
    707 
    708 /** Constructor.
    709  *
    710  *  @param context Rendering context.
    711  *
    712  **/
    713 GPUShader5FunctionOverloadingTest::GPUShader5FunctionOverloadingTest(deqp::Context& context)
    714 	: GPUShader5ImplicitConversionsTest(context, "function_overloading",
    715 										"Verifies that function overloading is accepted")
    716 {
    717 	/* Left blank intentionally */
    718 }
    719 
    720 /** Executes test iteration.
    721  *
    722  *  @return Returns STOP.
    723  */
    724 tcu::TestNode::IterateResult GPUShader5FunctionOverloadingTest::iterate()
    725 {
    726 	/* Defines data used as u1 and u2 uniforms */
    727 	static const glw::GLint  u1_data_1[4] = { (glw::GLint)0xffff0000, 0x0000ffff, 0x00ffffff, (glw::GLint)0xffffffff };
    728 	static const glw::GLint  u1_data_2[4] = { -112, 1122, -111222, 1222111222 };
    729 	static const glw::GLuint u2_data_1[4] = { 0xffff0000, 0x0000ffff, 0x00ffffff, 0xffffffff };
    730 	static const glw::GLuint u2_data_2[4] = { 0xfff70000, 0x00007fff, 0x007fffff, 0xfffffff7 };
    731 
    732 	testInit();
    733 
    734 	/* Execute test case */
    735 	execute(u1_data_1, u2_data_1, true);
    736 	execute(u1_data_2, u2_data_2, false);
    737 
    738 	/* Set result - exceptions are thrown in case of any error */
    739 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
    740 
    741 	/* Done */
    742 	return STOP;
    743 }
    744 
    745 /** Executes test case
    746  *
    747  * @param u1_data   Pointer to data that will used as u1 uniform
    748  * @param u2_data   Pointer to data that will used as u2 uniform
    749  * @param test_case Defines test case parameters
    750  */
    751 void GPUShader5FunctionOverloadingTest::execute(const glw::GLint* u1_data, const glw::GLuint* u2_data,
    752 												bool is_black_expected)
    753 {
    754 	static const glw::GLuint black_color = 0x00000000;
    755 
    756 	/*  */
    757 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    758 
    759 	/* Run test case */
    760 	{
    761 		/* Shaders */
    762 		const char* fs = "#version 150\n"
    763 						 "\n"
    764 						 "in  vec4 result;\n"
    765 						 "out vec4 color;\n"
    766 						 "\n"
    767 						 "void main()\n"
    768 						 "{\n"
    769 						 "    color = result;\n"
    770 						 "}\n"
    771 						 "\n";
    772 
    773 		const char* vs = "#version 150\n"
    774 						 "#extension GL_ARB_gpu_shader5 : require\n"
    775 						 "\n"
    776 						 "uniform ivec4 u1;\n"
    777 						 "uniform uvec4 u2;\n"
    778 						 "\n"
    779 						 "out     vec4  result;\n"
    780 						 "\n"
    781 						 "vec4 f(in vec4 a, in vec4 b)\n"
    782 						 "{\n"
    783 						 "    return a * b;\n"
    784 						 "}\n"
    785 						 "\n"
    786 						 "vec4 f(in uvec4 a, in uvec4 b)\n"
    787 						 "{\n"
    788 						 "    return vec4(a - b);\n"
    789 						 "}\n"
    790 						 "\n"
    791 						 "void main()\n"
    792 						 "{\n"
    793 						 "    result = f(u1, u2);\n"
    794 						 "\n"
    795 						 "    switch (gl_VertexID)\n"
    796 						 "    {\n"
    797 						 "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
    798 						 "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
    799 						 "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
    800 						 "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
    801 						 "    }\n"
    802 						 "}\n"
    803 						 "\n";
    804 
    805 		/* Prepare program */
    806 		Utils::programInfo program(m_context);
    807 
    808 		program.build(fs, vs);
    809 
    810 		gl.useProgram(program.m_program_object_id);
    811 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
    812 
    813 		program.setUniform(Utils::VARIABLE_TYPE_IVEC4, "u1", u1_data);
    814 		program.setUniform(Utils::VARIABLE_TYPE_UVEC4, "u2", u2_data);
    815 
    816 		/* Clear FBO */
    817 		gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
    818 		GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
    819 
    820 		gl.clear(GL_COLOR_BUFFER_BIT);
    821 		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
    822 
    823 		/* Draw a triangle strip */
    824 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
    825 		GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
    826 	}
    827 
    828 	/* Verification */
    829 	verifyImage(black_color, is_black_expected);
    830 }
    831 
    832 /** Constructor.
    833  *
    834  *  @param context Rendering context.
    835  *
    836  **/
    837 GPUShader5FloatEncodingTest::GPUShader5FloatEncodingTest(deqp::Context& context)
    838 	: GPUShader5ImplicitConversionsTest(context, "float_encoding",
    839 										"Verifies that functions encoding floats as bits work as expected")
    840 {
    841 	/* Left blank intentionally */
    842 }
    843 
    844 /** Executes test iteration.
    845  *
    846  *  @return Returns STOP.
    847  */
    848 tcu::TestNode::IterateResult GPUShader5FloatEncodingTest::iterate()
    849 {
    850 	/* Defines data used as u1 and u2 uniforms */
    851 	static const glw::GLfloat floats[4] = { -1.0f, -1234.0f, 1.0f, 1234.0f };
    852 	static const glw::GLint   ints[4]   = { -1, -1234, 1, 1234 };
    853 	static const glw::GLuint  uints[4]  = { 0xffffffff, 0xfffffb2e, 1, 0x4d2 };
    854 
    855 	/* Defines tested cases */
    856 	static const testCase test_cases[] = {
    857 		{ /* float >> int - invalid */
    858 		  { Utils::VARIABLE_TYPE_INT, "int", ints },
    859 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    860 		  "floatBitsToInt",
    861 		  false },
    862 		{ /* float >> int - valid */
    863 		  { Utils::VARIABLE_TYPE_INT, "int", floats },
    864 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    865 		  "floatBitsToInt",
    866 		  true },
    867 		{ /* vec2 >> ivec2 - invalid */
    868 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", ints },
    869 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    870 		  "floatBitsToInt",
    871 		  false },
    872 		{ /* vec2 >> ivec2 - valid */
    873 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", floats },
    874 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    875 		  "floatBitsToInt",
    876 		  true },
    877 		{ /* vec3 >> ivec3 - invalid */
    878 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", ints },
    879 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    880 		  "floatBitsToInt",
    881 		  false },
    882 		{ /* vec3 >> ivec3 - valid */
    883 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", floats },
    884 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    885 		  "floatBitsToInt",
    886 		  true },
    887 		{ /* vec4 >> ivec4 - invalid */
    888 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", ints },
    889 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
    890 		  "floatBitsToInt",
    891 		  false },
    892 		{ /* vec4 >> ivec4 - valid */
    893 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", floats },
    894 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
    895 		  "floatBitsToInt",
    896 		  true },
    897 		{ /* float >> uint - invalid */
    898 		  { Utils::VARIABLE_TYPE_UINT, "uint", uints },
    899 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    900 		  "floatBitsToUint",
    901 		  false },
    902 		{ /* float >> uint - valid */
    903 		  { Utils::VARIABLE_TYPE_UINT, "uint", floats },
    904 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    905 		  "floatBitsToUint",
    906 		  true },
    907 		{ /* vec2 >> uvec2 - invalid */
    908 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", uints },
    909 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    910 		  "floatBitsToUint",
    911 		  false },
    912 		{ /* vec2 >> uvec2 - valid */
    913 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", floats },
    914 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    915 		  "floatBitsToUint",
    916 		  true },
    917 		{ /* vec3 >> uvec3 - invalid */
    918 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", uints },
    919 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    920 		  "floatBitsToUint",
    921 		  false },
    922 		{ /* vec3 >> uvec3 - valid */
    923 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", floats },
    924 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    925 		  "floatBitsToUint",
    926 		  true },
    927 		{ /* vec4 >> ivec4 - invalid */
    928 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", uints },
    929 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
    930 		  "floatBitsToUint",
    931 		  false },
    932 		{ /* vec4 >> uvec4 - valid */
    933 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", floats },
    934 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
    935 		  "floatBitsToUint",
    936 		  true },
    937 		{ /* int >> float - invalid */
    938 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    939 		  { Utils::VARIABLE_TYPE_INT, "int", ints },
    940 		  "intBitsToFloat",
    941 		  false },
    942 		{ /* int >> float - valid */
    943 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    944 		  { Utils::VARIABLE_TYPE_INT, "int", floats },
    945 		  "intBitsToFloat",
    946 		  true },
    947 		{ /* ivec2 >> vec2 - invalid */
    948 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    949 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", ints },
    950 		  "intBitsToFloat",
    951 		  false },
    952 		{ /* ivec2 >> vec2 - valid */
    953 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    954 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", floats },
    955 		  "intBitsToFloat",
    956 		  true },
    957 		{ /* ivec3 >> vec3 - invalid */
    958 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    959 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", ints },
    960 		  "intBitsToFloat",
    961 		  false },
    962 		{ /* ivec3 >> vec3 - valid */
    963 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    964 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", floats },
    965 		  "intBitsToFloat",
    966 		  true },
    967 		{ /* ivec4 >> vec4 - invalid */
    968 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
    969 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", ints },
    970 		  "intBitsToFloat",
    971 		  false },
    972 		{ /* ivec4 >> vec4 - valid */
    973 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
    974 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", floats },
    975 		  "intBitsToFloat",
    976 		  true },
    977 		{ /* uint >> float - invalid */
    978 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    979 		  { Utils::VARIABLE_TYPE_UINT, "uint", uints },
    980 		  "uintBitsToFloat",
    981 		  false },
    982 		{ /* uint >> float - valid */
    983 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
    984 		  { Utils::VARIABLE_TYPE_UINT, "uint", floats },
    985 		  "uintBitsToFloat",
    986 		  true },
    987 		{ /* uvec2 >> vec2 - invalid */
    988 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    989 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", uints },
    990 		  "uintBitsToFloat",
    991 		  false },
    992 		{ /* uvec2 >> vec2 - valid */
    993 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
    994 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", floats },
    995 		  "uintBitsToFloat",
    996 		  true },
    997 		{ /* uvec3 >> vec3 - invalid */
    998 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
    999 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", uints },
   1000 		  "uintBitsToFloat",
   1001 		  false },
   1002 		{ /* uvec3 >> vec3 - valid */
   1003 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
   1004 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", floats },
   1005 		  "uintBitsToFloat",
   1006 		  true },
   1007 		{ /* uvec4 >> vec4 - invalid */
   1008 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
   1009 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", uints },
   1010 		  "uintBitsToFloat",
   1011 		  false },
   1012 		{ /* uvec4 >> vec4 - valid */
   1013 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
   1014 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", floats },
   1015 		  "uintBitsToFloat",
   1016 		  true },
   1017 	};
   1018 	static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
   1019 
   1020 	testInit();
   1021 
   1022 	/* Execute test case */
   1023 	for (size_t i = 0; i < n_test_cases; ++i)
   1024 	{
   1025 		const testCase& test_case = test_cases[i];
   1026 
   1027 		execute(test_case);
   1028 	}
   1029 
   1030 	/* Set result - exceptions are thrown in case of any error */
   1031 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1032 
   1033 	/* Done */
   1034 	return STOP;
   1035 }
   1036 
   1037 /** Executes test case
   1038  *
   1039  * @param test_case Tested case
   1040  *
   1041  * @param test_case Defines test case parameters
   1042  */
   1043 void GPUShader5FloatEncodingTest::execute(const testCase& test_case)
   1044 {
   1045 	static const glw::GLuint white_color = 0xffffffff;
   1046 
   1047 	/*  */
   1048 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1049 
   1050 	/* Run test case */
   1051 	{
   1052 		/* Shaders */
   1053 		const char* fs = "#version 150\n"
   1054 						 "\n"
   1055 						 "in  vec4 result;\n"
   1056 						 "out vec4 color;\n"
   1057 						 "\n"
   1058 						 "void main()\n"
   1059 						 "{\n"
   1060 						 "    color = result;\n"
   1061 						 "}\n"
   1062 						 "\n";
   1063 
   1064 		const std::string& vs = getVertexShader(test_case);
   1065 
   1066 		/* Prepare program */
   1067 		Utils::programInfo program(m_context);
   1068 
   1069 		program.build(fs, vs.c_str());
   1070 
   1071 		gl.useProgram(program.m_program_object_id);
   1072 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
   1073 
   1074 		program.setUniform(test_case.m_expected_value.m_type, "expected_value", test_case.m_expected_value.m_data);
   1075 		program.setUniform(test_case.m_value.m_type, "value", test_case.m_value.m_data);
   1076 
   1077 		/* Clear FBO */
   1078 		gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
   1079 		GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
   1080 
   1081 		gl.clear(GL_COLOR_BUFFER_BIT);
   1082 		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
   1083 
   1084 		/* Draw a triangle strip */
   1085 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
   1086 		GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
   1087 	}
   1088 
   1089 	/* Verification */
   1090 	verifyImage(white_color, test_case.m_is_white_expected);
   1091 }
   1092 
   1093 /** Get vertex shader source.
   1094  *
   1095  * @param test_case Tested case
   1096  *
   1097  * @return String with source of shader
   1098  */
   1099 std::string GPUShader5FloatEncodingTest::getVertexShader(const testCase& test_case) const
   1100 {
   1101 	/* Vertex shader template */
   1102 	const char* vs_body_template = "#version 150\n"
   1103 								   "#extension GL_ARB_gpu_shader5 : require\n"
   1104 								   "\n"
   1105 								   "uniform EXPECTED_VALUE_TYPE expected_value;\n"
   1106 								   "uniform VALUE_TYPE value;\n"
   1107 								   "\n"
   1108 								   "out     vec4 result;\n"
   1109 								   "\n"
   1110 								   "void main()\n"
   1111 								   "{\n"
   1112 								   "    result = vec4(1.0, 1.0, 1.0, 1.0);\n"
   1113 								   "\n"
   1114 								   "    EXPECTED_VALUE_TYPE ret_val = TESTED_FUNCTION(value);\n"
   1115 								   "\n"
   1116 								   "    if (expected_value != ret_val)\n"
   1117 								   "    {\n"
   1118 								   "        result = vec4(0.0, 0.0, 0.0, 0.0);\n"
   1119 								   "    }\n"
   1120 								   "\n"
   1121 								   "    switch (gl_VertexID)\n"
   1122 								   "    {\n"
   1123 								   "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
   1124 								   "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
   1125 								   "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
   1126 								   "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
   1127 								   "    }\n"
   1128 								   "}\n"
   1129 								   "\n";
   1130 
   1131 	std::string vs_body = vs_body_template;
   1132 
   1133 	/* Tokens */
   1134 	size_t search_position = 0;
   1135 
   1136 	Utils::replaceToken("EXPECTED_VALUE_TYPE", search_position, test_case.m_expected_value.m_type_name, vs_body);
   1137 	Utils::replaceToken("VALUE_TYPE", search_position, test_case.m_value.m_type_name, vs_body);
   1138 	Utils::replaceToken("EXPECTED_VALUE_TYPE", search_position, test_case.m_expected_value.m_type_name, vs_body);
   1139 	Utils::replaceToken("TESTED_FUNCTION", search_position, test_case.m_function_name, vs_body);
   1140 
   1141 	return vs_body;
   1142 }
   1143 
   1144 /** Constructor.
   1145  *
   1146  *  @param context Rendering context.
   1147  **/
   1148 GPUShader5Tests::GPUShader5Tests(deqp::Context& context)
   1149 	: TestCaseGroup(context, "gpu_shader5_gl", "Verifies \"gpu_shader5\" functionality")
   1150 {
   1151 	/* Left blank on purpose */
   1152 }
   1153 
   1154 /** Initializes a texture_storage_multisample test group.
   1155  *
   1156  **/
   1157 void GPUShader5Tests::init(void)
   1158 {
   1159 	addChild(new GPUShader5ImplicitConversionsTest(m_context));
   1160 	addChild(new GPUShader5FunctionOverloadingTest(m_context));
   1161 	addChild(new GPUShader5FloatEncodingTest(m_context));
   1162 }
   1163 } /* glcts namespace */
   1164