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  gl3cTextureSizePromotionTests.hpp
     26  * \brief Implements test classes for testing of texture internal format
     27  promotion mechanism.
     28  */ /*-------------------------------------------------------------------*/
     29 
     30 #include "gl3cTextureSizePromotion.hpp"
     31 
     32 #include "deMath.h"
     33 #include "gluContextInfo.hpp"
     34 #include "gluStrUtil.hpp"
     35 #include "glwFunctions.hpp"
     36 #include "tcuTestLog.hpp"
     37 
     38 /* Stringify macro. */
     39 #define _STR(s) STR(s)
     40 #define STR(s) #s
     41 
     42 namespace gl3cts
     43 {
     44 namespace TextureSizePromotion
     45 {
     46 Tests::Tests(deqp::Context& context)
     47 	: TestCaseGroup(context, "texture_size_promotion", "Verifies texture internal format size promotion mechanism.")
     48 {
     49 	/* Left blank on purpose */
     50 }
     51 
     52 void Tests::init(void)
     53 {
     54 	addChild(new TextureSizePromotion::FunctionalTest(m_context));
     55 }
     56 
     57 /*===========================================================================================================*/
     58 
     59 FunctionalTest::FunctionalTest(deqp::Context& context)
     60 	: TestCase(context, "functional", "Verifies that texture internal format size promotion mechanism can be used.")
     61 	, m_vao(0)
     62 	, m_source_texture(0)
     63 	, m_destination_texture(0)
     64 	, m_framebuffer(0)
     65 	, m_program(0)
     66 	, m_max_samples(0)
     67 {
     68 	/* Left blank on purpose */
     69 }
     70 
     71 tcu::TestNode::IterateResult FunctionalTest::iterate()
     72 {
     73 	/* Get context setup. */
     74 	glu::ContextType context_type = m_context.getRenderContext().getType();
     75 	bool			 is_arb_texture_storage_multisample =
     76 		m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
     77 
     78 	/* Prepare initial results. */
     79 	bool is_ok	 = true;
     80 	bool was_error = false;
     81 
     82 	/* Iterate over test cases. */
     83 	try
     84 	{
     85 		/* Only for OpenGL 3.1 context. */
     86 		if (glu::contextSupports(context_type, glu::ApiType::core(3, 1)))
     87 		{
     88 			/* Generate and bind VAO. */
     89 			prepareVertexArrayObject();
     90 
     91 			/* For every required format */
     92 			for (glw::GLuint i = 0; i < s_formats_size; ++i)
     93 			{
     94 				/* Test only if format is required by context. */
     95 				if (glu::contextSupports(context_type, s_formats[i].required_by_context.getAPI()))
     96 				{
     97 					/* For every target. */
     98 					for (glw::GLuint j = 0; j < s_source_texture_targets_count; ++j)
     99 					{
    100 						/* Test if it is supported by context or internal format. */
    101 						if (isTargetMultisampled(s_source_texture_targets[j]))
    102 						{
    103 							if ((!is_arb_texture_storage_multisample) &&
    104 								(!glu::contextSupports(context_type, glu::ApiType::core(4, 3))))
    105 							{
    106 								continue;
    107 							}
    108 
    109 							if (!s_formats[i]
    110 									 .is_color_renderable) /* Multisampled textures need to be set using rendering. */
    111 							{
    112 								continue;
    113 							}
    114 
    115 							if (isDepthType(s_formats[i]) || isStencilType(s_formats[i]))
    116 							{
    117 								continue;
    118 							}
    119 						}
    120 
    121 						if ((isDepthType(s_formats[i]) || isStencilType(s_formats[i])) &&
    122 							(GL_TEXTURE_3D == s_source_texture_targets[j]))
    123 						{
    124 							continue;
    125 						}
    126 
    127 						/* Prepare source texture to be tested. */
    128 						prepareSourceTexture(s_formats[i], s_source_texture_targets[j]);
    129 
    130 						/* Check basic API queries for source texture. */
    131 						is_ok = is_ok & checkSourceTextureSizeAndType(s_formats[i], s_source_texture_targets[j]);
    132 
    133 						/* For every [R, G, B, A] component. */
    134 						for (glw::GLuint k = 0; k < COMPONENTS_COUNT; ++k)
    135 						{
    136 							/* Prepare destination texture. */
    137 							prepareDestinationTextureAndFramebuffer(s_formats[i], GL_TEXTURE_2D);
    138 
    139 							/* Building program (throws on failure). */
    140 							m_program =
    141 								prepareProgram(s_source_texture_targets[j], s_formats[i], ColorChannelSelector(k));
    142 
    143 							/* Setup GL and draw. */
    144 							makeProgramAndSourceTextureActive(s_source_texture_targets[j]);
    145 
    146 							drawQuad();
    147 
    148 							/* Check results. */
    149 							is_ok = is_ok & checkDestinationTexture(s_formats[i], ColorChannelSelector(k),
    150 																	s_source_texture_targets[j],
    151 																	s_source_texture_targets_names[j]);
    152 
    153 							/* Cleanup. */
    154 							cleanDestinationTexture();
    155 							cleanFramebuffer();
    156 							cleanProgram();
    157 						}
    158 
    159 						cleanSourceTexture();
    160 					}
    161 				}
    162 			}
    163 		}
    164 	}
    165 	catch (...)
    166 	{
    167 		/* Error have occured. */
    168 		is_ok	 = false;
    169 		was_error = true;
    170 	}
    171 
    172 	/* Clean all. */
    173 
    174 	cleanSourceTexture();
    175 	cleanDestinationTexture();
    176 	cleanFramebuffer();
    177 	cleanProgram();
    178 	cleanVertexArrayObject();
    179 
    180 	/* Result's setup. */
    181 	if (is_ok)
    182 	{
    183 		/* Log success. */
    184 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Texture Size Promotion Test have passed."
    185 											<< tcu::TestLog::EndMessage;
    186 
    187 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    188 	}
    189 	else
    190 	{
    191 		if (was_error)
    192 		{
    193 			/* Log error. */
    194 			m_context.getTestContext().getLog() << tcu::TestLog::Message
    195 												<< "Texture Size Promotion Test have approached error."
    196 												<< tcu::TestLog::EndMessage;
    197 
    198 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    199 		}
    200 		else
    201 		{
    202 			/* Log fail. */
    203 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Texture Size Promotion Test have failed."
    204 												<< tcu::TestLog::EndMessage;
    205 
    206 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    207 		}
    208 	}
    209 
    210 	/* End test. */
    211 	return tcu::TestNode::STOP;
    212 }
    213 
    214 void FunctionalTest::prepareVertexArrayObject()
    215 {
    216 	/* GL functions object. */
    217 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    218 
    219 	gl.genVertexArrays(1, &m_vao);
    220 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed");
    221 
    222 	gl.bindVertexArray(m_vao);
    223 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray have failed");
    224 }
    225 
    226 void FunctionalTest::prepareSourceTexture(TextureInternalFormatDescriptor descriptor, glw::GLenum target)
    227 {
    228 	/* GL functions object. */
    229 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    230 
    231 	/* Create and bind texture object. */
    232 	gl.genTextures(1, &m_source_texture);
    233 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    234 
    235 	gl.bindTexture(target, m_source_texture);
    236 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    237 
    238 	/* Select proper data set. */
    239 	glw::GLvoid* source_data   = DE_NULL;
    240 	glw::GLenum  source_type   = GL_NONE;
    241 	glw::GLenum  source_format = GL_RGBA;
    242 
    243 	if (isFloatType(descriptor)) /* For floating type. */
    244 	{
    245 		source_data   = (glw::GLvoid*)s_source_texture_data_f;
    246 		source_type   = GL_FLOAT;
    247 		source_format = GL_RGBA;
    248 	}
    249 	else
    250 	{
    251 		if (isFixedSignedType(descriptor)) /* For fixed signed type. */
    252 		{
    253 			source_data   = (glw::GLvoid*)s_source_texture_data_sn;
    254 			source_type   = GL_FLOAT;
    255 			source_format = GL_RGBA;
    256 		}
    257 		else
    258 		{
    259 			if (isFixedUnsignedType(descriptor)) /* For fixed unsigned type. */
    260 			{
    261 				source_data   = (glw::GLvoid*)s_source_texture_data_n;
    262 				source_type   = GL_FLOAT;
    263 				source_format = GL_RGBA;
    264 			}
    265 			else
    266 			{
    267 				if (isIntegerSignedType(descriptor)) /* For integral signed type. */
    268 				{
    269 					source_data   = (glw::GLvoid*)s_source_texture_data_i;
    270 					source_type   = GL_INT;
    271 					source_format = GL_RGBA_INTEGER;
    272 				}
    273 				else
    274 				{
    275 					if (isIntegerUnsignedType(descriptor)) /* For integral unsigned type. */
    276 					{
    277 						source_data   = (glw::GLvoid*)s_source_texture_data_ui;
    278 						source_type   = GL_UNSIGNED_INT;
    279 						source_format = GL_RGBA_INTEGER;
    280 					}
    281 					else
    282 					{
    283 						if (isDepthType(descriptor)) /* For depth type. */
    284 						{
    285 							source_data   = NULL;
    286 							source_type   = GL_UNSIGNED_INT;
    287 							source_format = GL_DEPTH_COMPONENT;
    288 						}
    289 						else
    290 						{
    291 							if (isStencilType(descriptor)) /* For stencil type. */
    292 							{
    293 								source_data   = NULL;
    294 								source_type   = GL_UNSIGNED_INT;
    295 								source_format = GL_STENCIL_INDEX;
    296 							}
    297 						}
    298 					}
    299 				}
    300 			}
    301 		}
    302 	}
    303 
    304 	/* Prepare texture storage depending on the target. */
    305 	switch (target)
    306 	{
    307 	case GL_TEXTURE_1D:
    308 		gl.texImage1D(target, 0, descriptor.internal_format, s_source_texture_size, 0, source_format, source_type,
    309 					  source_data);
    310 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    311 		break;
    312 	case GL_TEXTURE_1D_ARRAY:
    313 	case GL_TEXTURE_2D:
    314 	case GL_TEXTURE_RECTANGLE:
    315 		gl.texImage2D(target, 0, descriptor.internal_format, s_source_texture_size, s_source_texture_size, 0,
    316 					  source_format, source_type, source_data);
    317 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    318 		break;
    319 	case GL_TEXTURE_2D_ARRAY:
    320 	case GL_TEXTURE_3D:
    321 		gl.texImage3D(target, 0, descriptor.internal_format, s_source_texture_size, s_source_texture_size,
    322 					  s_source_texture_size, 0, source_format, source_type, source_data);
    323 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    324 		break;
    325 	case GL_TEXTURE_2D_MULTISAMPLE:
    326 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
    327 		renderDataIntoMultisampledTexture(descriptor, target);
    328 		break;
    329 	default:
    330 		throw 0;
    331 	}
    332 }
    333 
    334 void FunctionalTest::renderDataIntoMultisampledTexture(TextureInternalFormatDescriptor descriptor, glw::GLenum target)
    335 {
    336 	/* GL functions object. */
    337 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    338 
    339 	/* Fetch limits. */
    340 	gl.getIntegerv(GL_MAX_SAMPLES, &m_max_samples);
    341 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
    342 
    343 	if (m_max_samples == 0)
    344 	{
    345 		m_max_samples = 1;
    346 	}
    347 
    348 	/* Setup target. */
    349 	glw::GLenum non_ms_target = (target == GL_TEXTURE_2D_MULTISAMPLE) ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY;
    350 
    351 	/* Cleanup required by prepareSourceTexture(...). */
    352 	cleanSourceTexture();
    353 
    354 	/* Prepare textures and program. */
    355 	prepareSourceTexture(descriptor, non_ms_target);
    356 
    357 	prepareDestinationTextureAndFramebuffer(descriptor, target);
    358 
    359 	m_program = prepareProgram(non_ms_target, descriptor, COMPONENTS_COUNT);
    360 
    361 	/* Setup GL and render texture. */
    362 	makeProgramAndSourceTextureActive(non_ms_target);
    363 
    364 	drawQuad();
    365 
    366 	/* Cleanup. */
    367 	cleanFramebuffer();
    368 	cleanSourceTexture();
    369 
    370 	/* Swpaing destination texture to source texture. */
    371 	m_source_texture = m_destination_texture;
    372 
    373 	m_destination_texture = 0;
    374 
    375 	/* Clean program. */
    376 	cleanProgram();
    377 }
    378 
    379 void FunctionalTest::prepareDestinationTextureAndFramebuffer(TextureInternalFormatDescriptor descriptor,
    380 															 glw::GLenum					 target)
    381 {
    382 	/* GL functions object. */
    383 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    384 
    385 	/* Get internal format. */
    386 	glw::GLenum internal_format = getDestinationFormatForChannel(descriptor);
    387 
    388 	/* Create framebuffer object. */
    389 	gl.genFramebuffers(1, &m_framebuffer);
    390 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
    391 
    392 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
    393 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
    394 
    395 	/* Create framebuffer's destination texture. */
    396 	gl.genTextures(1, &m_destination_texture);
    397 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    398 
    399 	gl.bindTexture(target, m_destination_texture);
    400 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    401 
    402 	/* Allocate texture storage and upload data for test rendering. */
    403 	if (target == GL_TEXTURE_2D)
    404 	{
    405 		glw::GLenum  destination_format = GL_RED;
    406 		glw::GLenum  destination_type   = GL_FLOAT;
    407 		glw::GLvoid* destination_data   = (glw::GLvoid*)s_destination_texture_data_f;
    408 
    409 		if (isIntegerSignedType(descriptor))
    410 		{
    411 			destination_format = GL_RED_INTEGER;
    412 			destination_type   = GL_INT;
    413 			destination_data   = (glw::GLvoid*)s_destination_texture_data_i;
    414 		}
    415 
    416 		if (isIntegerUnsignedType(descriptor))
    417 		{
    418 			destination_format = GL_RED_INTEGER;
    419 			destination_type   = GL_UNSIGNED_INT;
    420 			destination_data   = (glw::GLvoid*)s_destination_texture_data_ui;
    421 		}
    422 
    423 		gl.texImage2D(target, 0, internal_format, s_source_texture_size, s_source_texture_size, 0, destination_format,
    424 					  destination_type, destination_data);
    425 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    426 
    427 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_destination_texture, 0);
    428 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D have failed");
    429 	}
    430 	else /* Allocate texture storage for uploading datat for multisampled targets (upload must be done via shader). */
    431 	{
    432 		if (target == GL_TEXTURE_2D_MULTISAMPLE)
    433 		{
    434 			gl.texImage2DMultisample(target, m_max_samples - 1, descriptor.internal_format, s_source_texture_size,
    435 									 s_source_texture_size, GL_TRUE);
    436 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    437 
    438 			gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_destination_texture, 0);
    439 			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D have failed");
    440 		}
    441 		else
    442 		{
    443 			gl.texImage3DMultisample(target, m_max_samples - 1, descriptor.internal_format, s_source_texture_size,
    444 									 s_source_texture_size, s_source_texture_size, GL_TRUE);
    445 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    446 
    447 			gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_destination_texture, 0, 0);
    448 			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D have failed");
    449 		}
    450 	}
    451 
    452 	/* Check framebuffer completness. */
    453 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    454 	{
    455 		throw 0;
    456 	}
    457 
    458 	/* Setup viewport. */
    459 	gl.viewport(0, 0, s_source_texture_size, s_source_texture_size);
    460 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
    461 }
    462 
    463 void FunctionalTest::makeProgramAndSourceTextureActive(glw::GLenum target)
    464 {
    465 	/* GL functions object. */
    466 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    467 
    468 	/* Use GLSL program. */
    469 	gl.useProgram(m_program);
    470 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram have failed");
    471 
    472 	/* Setup source texture. */
    473 	gl.activeTexture(GL_TEXTURE0);
    474 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture have failed");
    475 
    476 	gl.bindTexture(target, m_source_texture);
    477 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    478 
    479 	glw::GLint location = gl.getUniformLocation(m_program, "data");
    480 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation have failed");
    481 
    482 	gl.uniform1i(location, 0);
    483 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i have failed");
    484 }
    485 
    486 bool FunctionalTest::checkSourceTextureSizeAndType(TextureInternalFormatDescriptor descriptor, glw::GLenum target)
    487 {
    488 	/* GL functions object. */
    489 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    490 
    491 	/* query result storage */
    492 	glw::GLint red_size		= 0;
    493 	glw::GLint blue_size	= 0;
    494 	glw::GLint green_size   = 0;
    495 	glw::GLint alpha_size   = 0;
    496 	glw::GLint depth_size   = 0;
    497 	glw::GLint stencil_size = 0;
    498 
    499 	glw::GLint red_type   = 0;
    500 	glw::GLint green_type = 0;
    501 	glw::GLint blue_type  = 0;
    502 	glw::GLint alpha_type = 0;
    503 	glw::GLint depth_type = 0;
    504 
    505 	/* Bind texture */
    506 	gl.bindTexture(target, m_source_texture);
    507 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    508 
    509 	/* queries */
    510 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_RED_SIZE, &red_size);
    511 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
    512 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
    513 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
    514 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_SIZE, &depth_size);
    515 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_STENCIL_SIZE, &stencil_size);
    516 
    517 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_RED_TYPE, &red_type);
    518 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_TYPE, &green_type);
    519 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_TYPE, &blue_type);
    520 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_TYPE, &alpha_type);
    521 	gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_TYPE, &depth_type);
    522 
    523 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv have failed");
    524 
    525 	/* check expected values */
    526 	bool is_ok = true;
    527 
    528 	is_ok = is_ok && (red_size >= descriptor.min_red_size);
    529 	is_ok = is_ok && (green_size >= descriptor.min_green_size);
    530 	is_ok = is_ok && (blue_size >= descriptor.min_blue_size);
    531 	is_ok = is_ok && (alpha_size >= descriptor.min_alpha_size);
    532 	is_ok = is_ok && (depth_size >= descriptor.min_depth_size);
    533 	is_ok = is_ok && (stencil_size >= descriptor.min_stencil_size);
    534 
    535 	is_ok = is_ok && ((glw::GLenum)red_type == descriptor.expected_red_type);
    536 	is_ok = is_ok && ((glw::GLenum)green_type == descriptor.expected_green_type);
    537 	is_ok = is_ok && ((glw::GLenum)blue_type == descriptor.expected_blue_type);
    538 	is_ok = is_ok && ((glw::GLenum)alpha_type == descriptor.expected_alpha_type);
    539 	is_ok = is_ok && ((glw::GLenum)depth_type == descriptor.expected_depth_type);
    540 
    541 	/* Log on failure. */
    542 	if (!is_ok)
    543 	{
    544 		m_context.getTestContext().getLog()
    545 			<< tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
    546 			<< " have failed during glGetTexLevelParameteriv query. "
    547 			<< "Expected red size = " << descriptor.min_red_size
    548 			<< ", expected green size = " << descriptor.min_green_size
    549 			<< ", expected blue size = " << descriptor.min_blue_size
    550 			<< ", expected alpha size = " << descriptor.min_alpha_size
    551 			<< ", expected depth size = " << descriptor.min_depth_size
    552 			<< ", expected stencil size = " << descriptor.min_stencil_size << ". Queried red size = " << red_size
    553 			<< ", queried green size = " << green_size << ", queried blue size = " << blue_size
    554 			<< ", queried alpha size = " << alpha_size << ", queried depth size = " << depth_size
    555 			<< ", queried stencil size = " << stencil_size << ". "
    556 			<< "Expected red type = " << glu::getTypeStr(descriptor.expected_red_type)
    557 			<< ", expected green type = " << glu::getTypeStr(descriptor.expected_green_type)
    558 			<< ", expected blue type = " << glu::getTypeStr(descriptor.expected_blue_type)
    559 			<< ", expected alpha type = " << glu::getTypeStr(descriptor.expected_alpha_type)
    560 			<< ", expected depth type = " << glu::getTypeStr(descriptor.expected_depth_type)
    561 			<< ". Queried red type = " << glu::getTypeStr(red_type)
    562 			<< ", queried green type = " << glu::getTypeStr(green_type)
    563 			<< ", queried blue type = " << glu::getTypeStr(blue_type)
    564 			<< ", queried alpha type = " << glu::getTypeStr(alpha_type)
    565 			<< ", queried depth type = " << glu::getTypeStr(depth_type) << "." << tcu::TestLog::EndMessage;
    566 	}
    567 
    568 	/* return results. */
    569 	return is_ok;
    570 }
    571 
    572 glw::GLenum FunctionalTest::getDestinationFormatForChannel(TextureInternalFormatDescriptor descriptor)
    573 {
    574 	if (isFloatType(descriptor))
    575 	{
    576 		return GL_R32F;
    577 	}
    578 
    579 	if (isFixedUnsignedType(descriptor))
    580 	{
    581 		return GL_R16;
    582 	}
    583 
    584 	if (isFixedSignedType(descriptor))
    585 	{
    586 		return GL_R16_SNORM;
    587 	}
    588 
    589 	if (isIntegerUnsignedType(descriptor))
    590 	{
    591 		return GL_R32UI;
    592 	}
    593 
    594 	if (isIntegerSignedType(descriptor))
    595 	{
    596 		return GL_R32I;
    597 	}
    598 
    599 	return GL_R32F;
    600 }
    601 
    602 glw::GLuint FunctionalTest::prepareProgram(glw::GLenum target, TextureInternalFormatDescriptor descriptor,
    603 										   ColorChannelSelector channel)
    604 {
    605 	/* GL functions object. */
    606 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    607 
    608 	/* Preparing sampler name and textelFetch arguments */
    609 	std::string sampler_name			   = "";
    610 	std::string texel_fetch_arguments_tail = "";
    611 
    612 	switch (target)
    613 	{
    614 	case GL_TEXTURE_1D:
    615 		sampler_name			   = "sampler1D";
    616 		texel_fetch_arguments_tail = "0, 0";
    617 		break;
    618 	case GL_TEXTURE_2D:
    619 		sampler_name			   = "sampler2D";
    620 		texel_fetch_arguments_tail = "ivec2(0), 0";
    621 		break;
    622 	case GL_TEXTURE_1D_ARRAY:
    623 		sampler_name			   = "sampler1DArray";
    624 		texel_fetch_arguments_tail = "ivec2(0), 0";
    625 		break;
    626 	case GL_TEXTURE_RECTANGLE:
    627 		sampler_name			   = "sampler2DRect";
    628 		texel_fetch_arguments_tail = "ivec2(0)";
    629 		break;
    630 	case GL_TEXTURE_2D_ARRAY:
    631 		sampler_name			   = "sampler2DArray";
    632 		texel_fetch_arguments_tail = "ivec3(0), 0";
    633 		break;
    634 	case GL_TEXTURE_3D:
    635 		sampler_name			   = "sampler3D";
    636 		texel_fetch_arguments_tail = "ivec3(0), 0";
    637 		break;
    638 	case GL_TEXTURE_2D_MULTISAMPLE:
    639 		sampler_name			   = "sampler2DMS";
    640 		texel_fetch_arguments_tail = "ivec2(0), ";
    641 		texel_fetch_arguments_tail.append(Utilities::itoa(m_max_samples - 1));
    642 		break;
    643 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
    644 		sampler_name			   = "sampler2DMSArray";
    645 		texel_fetch_arguments_tail = "ivec3(0), ";
    646 		texel_fetch_arguments_tail.append(Utilities::itoa(m_max_samples - 1));
    647 		break;
    648 	default:
    649 		throw 0;
    650 	}
    651 
    652 	/* Preparing component selector name */
    653 	std::string component_name = "";
    654 
    655 	switch (channel)
    656 	{
    657 	case RED_COMPONENT:
    658 		component_name = ".r";
    659 		break;
    660 	case GREEN_COMPONENT:
    661 		component_name = ".g";
    662 		break;
    663 	case BLUE_COMPONENT:
    664 		component_name = ".b";
    665 		break;
    666 	case ALPHA_COMPONENT:
    667 		component_name = ".a";
    668 		break;
    669 	case COMPONENTS_COUNT:
    670 		break;
    671 	default:
    672 		throw 0;
    673 	}
    674 
    675 	/* Preparing output type name and sampler prefix */
    676 	std::string type_name	  = "";
    677 	std::string sampler_prefix = "";
    678 
    679 	if (isFloatType(descriptor) || isFixedSignedType(descriptor) || isFixedUnsignedType(descriptor) ||
    680 		isDepthType(descriptor) || isStencilType(descriptor))
    681 	{
    682 		if (channel == COMPONENTS_COUNT)
    683 		{
    684 			type_name = "vec4";
    685 		}
    686 		else
    687 		{
    688 			type_name = "float";
    689 		}
    690 		sampler_prefix = "";
    691 	}
    692 	else
    693 	{
    694 		if (isIntegerSignedType(descriptor))
    695 		{
    696 			if (channel == COMPONENTS_COUNT)
    697 			{
    698 				type_name = "ivec4";
    699 			}
    700 			else
    701 			{
    702 				type_name = "int";
    703 			}
    704 			sampler_prefix = "i";
    705 		}
    706 		else
    707 		{
    708 			if (channel == COMPONENTS_COUNT)
    709 			{
    710 				type_name = "uvec4";
    711 			}
    712 			else
    713 			{
    714 				type_name = "uint";
    715 			}
    716 			sampler_prefix = "u";
    717 		}
    718 	}
    719 
    720 	std::string template_verison = "#version 150";
    721 
    722 	/* Preprocessing fragment shader source code. */
    723 	std::string fragment_shader = s_fragment_shader_template;
    724 
    725 	fragment_shader = Utilities::preprocessString(fragment_shader, "TEMPLATE_TYPE", type_name);
    726 	fragment_shader =
    727 		Utilities::preprocessString(fragment_shader, "TEMPLATE_SAMPLER", sampler_prefix.append(sampler_name));
    728 	fragment_shader =
    729 		Utilities::preprocessString(fragment_shader, "TEMPLATE_TEXEL_FETCH_ARGUMENTS", texel_fetch_arguments_tail);
    730 	fragment_shader = Utilities::preprocessString(fragment_shader, "TEMPLATE_COMPONENT", component_name);
    731 
    732 	/* Building program. */
    733 	glw::GLuint program =
    734 		Utilities::buildProgram(gl, m_context.getTestContext().getLog(), s_vertex_shader_code, fragment_shader.c_str());
    735 
    736 	if (0 == program)
    737 	{
    738 		throw 0;
    739 	}
    740 
    741 	/* Return program name. */
    742 	return program;
    743 }
    744 
    745 void FunctionalTest::drawQuad()
    746 {
    747 	/* GL functions object. */
    748 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    749 
    750 	/* Draw quad. */
    751 	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
    752 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays have failed");
    753 }
    754 
    755 void FunctionalTest::cleanSourceTexture()
    756 {
    757 	/* GL functions object. */
    758 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    759 
    760 	/* Delete object. */
    761 	if (m_source_texture)
    762 	{
    763 		gl.deleteTextures(1, &m_source_texture);
    764 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures have failed");
    765 
    766 		m_source_texture = 0;
    767 	}
    768 }
    769 
    770 void FunctionalTest::cleanDestinationTexture()
    771 {
    772 	/* GL functions object. */
    773 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    774 
    775 	/* Delete object. */
    776 	if (m_destination_texture)
    777 	{
    778 		gl.deleteTextures(1, &m_destination_texture);
    779 
    780 		m_destination_texture = 0;
    781 	}
    782 }
    783 
    784 void FunctionalTest::cleanFramebuffer()
    785 {
    786 	/* GL functions object. */
    787 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    788 
    789 	/* Delete object. */
    790 	if (m_framebuffer)
    791 	{
    792 		gl.deleteFramebuffers(1, &m_framebuffer);
    793 
    794 		m_framebuffer = 0;
    795 	}
    796 }
    797 
    798 void FunctionalTest::cleanProgram()
    799 {
    800 	/* GL functions object. */
    801 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    802 
    803 	/* Delete object. */
    804 	if (m_program)
    805 	{
    806 		gl.useProgram(0);
    807 
    808 		gl.deleteProgram(m_program);
    809 
    810 		m_program = 0;
    811 	}
    812 }
    813 
    814 void FunctionalTest::cleanVertexArrayObject()
    815 {
    816 	/* GL functions object. */
    817 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    818 
    819 	/* Delete object. */
    820 	if (m_vao)
    821 	{
    822 		gl.deleteVertexArrays(1, &m_vao);
    823 
    824 		m_vao = 0;
    825 	}
    826 }
    827 
    828 bool FunctionalTest::checkDestinationTexture(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel,
    829 											 glw::GLenum target, const glw::GLchar* target_name)
    830 {
    831 	/* GL functions object. */
    832 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    833 
    834 	/* Check depending on format. */
    835 	if (isFloatType(descriptor) || isDepthType(descriptor) || isStencilType(descriptor))
    836 	{
    837 		/* Fetch results from destination texture (attached to current framebuffer). */
    838 		glw::GLfloat pixel = 3.1415927f;
    839 		gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
    840 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
    841 
    842 		/* Setup expected value. */
    843 		glw::GLfloat expected_value = isChannelTypeNone(descriptor, channel) ?
    844 										  ((channel == ALPHA_COMPONENT) ? 1.f : 0.f) :
    845 										  s_source_texture_data_f[channel];
    846 
    847 		/* Compare expected and fetched values. */
    848 		if (fabs(pixel - expected_value) <= getMinPrecision(descriptor, channel))
    849 		{
    850 			/* Test succeeded*/
    851 			return true;
    852 		}
    853 		else
    854 		{
    855 			/* Log failure. */
    856 			m_context.getTestContext().getLog()
    857 				<< tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
    858 				<< " have failed during functional test of " << s_color_channel_names[channel]
    859 				<< " channel with target " << target_name << ". Expected value = " << expected_value
    860 				<< " read value = " << pixel << "." << tcu::TestLog::EndMessage;
    861 		}
    862 	}
    863 	else
    864 	{
    865 		if (isFixedSignedType(descriptor))
    866 		{
    867 			/* Fetch results from destination texture (attached to current framebuffer). */
    868 			glw::GLfloat pixel = 3.1415927f;
    869 			gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
    870 			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
    871 
    872 			/* Setup expected value. */
    873 			/* Signed fixed-point read color are clamped to [0, 1] by default */
    874 			glw::GLfloat expected_value = isChannelTypeNone(descriptor, channel) ?
    875 											  ((channel == ALPHA_COMPONENT) ? 1.f : 0.f) :
    876 											  deFloatClamp(s_source_texture_data_sn[channel], 0, 1);
    877 
    878 			/* Compare expected and fetched values. */
    879 			if (fabs(pixel - expected_value) <= getMinPrecision(descriptor, channel))
    880 			{
    881 				/* Test succeeded*/
    882 				return true;
    883 			}
    884 			else
    885 			{
    886 				/* Log failure. */
    887 				m_context.getTestContext().getLog()
    888 					<< tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
    889 					<< " have failed during functional test of " << s_color_channel_names[channel]
    890 					<< " channel with target " << target_name << ". Expected value = " << expected_value
    891 					<< " read value = " << pixel << "." << tcu::TestLog::EndMessage;
    892 			}
    893 		}
    894 		else
    895 		{
    896 			if (isFixedUnsignedType(descriptor))
    897 			{
    898 				/* Fetch results from destination texture (attached to current framebuffer). */
    899 				glw::GLfloat pixel = 3.1415927f;
    900 				gl.readPixels(0, 0, 1, 1, GL_RED, GL_FLOAT, &pixel);
    901 				GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
    902 
    903 				/* Setup expected value. */
    904 				glw::GLfloat expected_value = isChannelTypeNone(descriptor, channel) ?
    905 												  ((channel == ALPHA_COMPONENT) ? 1.f : 0.f) :
    906 												  s_source_texture_data_n[channel];
    907 
    908 				/* For sRGB internal formats convert value to linear space. */
    909 				if (descriptor.is_sRGB && (channel < ALPHA_COMPONENT))
    910 				{
    911 					expected_value = convert_from_sRGB(expected_value);
    912 
    913 					if (isTargetMultisampled(
    914 							target)) /* In multisampled targets two conversions are made (in upload and in shader) */
    915 					{
    916 						expected_value = convert_from_sRGB(expected_value);
    917 					}
    918 				}
    919 
    920 				/* Compare expected and fetched values. */
    921 				if (fabs(pixel - expected_value) <= getMinPrecision(descriptor, channel))
    922 				{
    923 					/* Test succeeded*/
    924 					return true;
    925 				}
    926 				else
    927 				{
    928 					/* Log failure. */
    929 					m_context.getTestContext().getLog()
    930 						<< tcu::TestLog::Message << "Promotion from internal format " << descriptor.internal_format_name
    931 						<< " have failed during functional test of " << s_color_channel_names[channel]
    932 						<< " channel with target " << target_name << ". Expected value = " << expected_value
    933 						<< " read value = " << pixel << "." << tcu::TestLog::EndMessage;
    934 				}
    935 			}
    936 			else
    937 			{
    938 				if (isIntegerSignedType(descriptor))
    939 				{
    940 					/* Fetch results from destination texture (attached to current framebuffer). */
    941 					glw::GLint pixel = 5;
    942 					gl.readPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_INT, &pixel);
    943 					GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
    944 
    945 					/* Setup expected value. */
    946 					glw::GLint expected_value = isChannelTypeNone(descriptor, channel) ?
    947 													((channel == ALPHA_COMPONENT) ? 1 : 0) :
    948 													s_source_texture_data_i[channel];
    949 
    950 					/* Compare expected and fetched values. */
    951 					if (pixel == expected_value)
    952 					{
    953 						/* Test succeeded*/
    954 						return true;
    955 					}
    956 					else
    957 					{
    958 						/* Log failure. */
    959 						m_context.getTestContext().getLog()
    960 							<< tcu::TestLog::Message << "Promotion from internal format "
    961 							<< descriptor.internal_format_name << " have failed during functional test of "
    962 							<< s_color_channel_names[channel] << " channel with target " << target_name
    963 							<< ". Expected value = " << expected_value << " read value = " << pixel << "."
    964 							<< tcu::TestLog::EndMessage;
    965 					}
    966 				}
    967 				else
    968 				{
    969 					if (isIntegerUnsignedType(descriptor))
    970 					{
    971 						/* Fetch results from destination texture (attached to current framebuffer). */
    972 						glw::GLuint pixel = 5;
    973 						gl.readPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixel);
    974 						GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels have failed");
    975 
    976 						/* Setup expected value. */
    977 						glw::GLuint expected_value = isChannelTypeNone(descriptor, channel) ?
    978 														 ((channel == ALPHA_COMPONENT) ? 1 : 0) :
    979 														 s_source_texture_data_ui[channel];
    980 
    981 						/* Compare expected and fetched values. */
    982 						if (pixel == expected_value)
    983 						{
    984 							/* Test succeeded*/
    985 							return true;
    986 						}
    987 						else
    988 						{
    989 							/* Log failure. */
    990 							m_context.getTestContext().getLog()
    991 								<< tcu::TestLog::Message << "Promotion from internal format "
    992 								<< descriptor.internal_format_name << " have failed during functional test of "
    993 								<< s_color_channel_names[channel] << " channel with target " << target_name
    994 								<< ". Expected value = " << expected_value << " read value = " << pixel << "."
    995 								<< tcu::TestLog::EndMessage;
    996 						}
    997 					}
    998 				}
    999 			}
   1000 		}
   1001 	}
   1002 
   1003 	/* Test failed. */
   1004 	return false;
   1005 }
   1006 
   1007 bool FunctionalTest::isFloatType(TextureInternalFormatDescriptor descriptor)
   1008 {
   1009 	return (GL_FLOAT == descriptor.expected_red_type) || (GL_FLOAT == descriptor.expected_green_type) ||
   1010 		   (GL_FLOAT == descriptor.expected_blue_type) || (GL_FLOAT == descriptor.expected_alpha_type);
   1011 }
   1012 
   1013 bool FunctionalTest::isFixedSignedType(TextureInternalFormatDescriptor descriptor)
   1014 {
   1015 	return (GL_SIGNED_NORMALIZED == descriptor.expected_red_type) ||
   1016 		   (GL_SIGNED_NORMALIZED == descriptor.expected_green_type) ||
   1017 		   (GL_SIGNED_NORMALIZED == descriptor.expected_blue_type) ||
   1018 		   (GL_SIGNED_NORMALIZED == descriptor.expected_alpha_type);
   1019 }
   1020 
   1021 bool FunctionalTest::isFixedUnsignedType(TextureInternalFormatDescriptor descriptor)
   1022 {
   1023 	return (GL_UNSIGNED_NORMALIZED == descriptor.expected_red_type) ||
   1024 		   (GL_UNSIGNED_NORMALIZED == descriptor.expected_green_type) ||
   1025 		   (GL_UNSIGNED_NORMALIZED == descriptor.expected_blue_type) ||
   1026 		   (GL_UNSIGNED_NORMALIZED == descriptor.expected_alpha_type);
   1027 }
   1028 
   1029 bool FunctionalTest::isIntegerSignedType(TextureInternalFormatDescriptor descriptor)
   1030 {
   1031 	return (GL_INT == descriptor.expected_red_type) || (GL_INT == descriptor.expected_green_type) ||
   1032 		   (GL_INT == descriptor.expected_blue_type) || (GL_INT == descriptor.expected_alpha_type);
   1033 }
   1034 
   1035 bool FunctionalTest::isIntegerUnsignedType(TextureInternalFormatDescriptor descriptor)
   1036 {
   1037 	return (GL_UNSIGNED_INT == descriptor.expected_red_type) || (GL_UNSIGNED_INT == descriptor.expected_green_type) ||
   1038 		   (GL_UNSIGNED_INT == descriptor.expected_blue_type) || (GL_UNSIGNED_INT == descriptor.expected_alpha_type);
   1039 }
   1040 
   1041 bool FunctionalTest::isDepthType(TextureInternalFormatDescriptor descriptor)
   1042 {
   1043 	return (GL_NONE != descriptor.expected_depth_type);
   1044 }
   1045 
   1046 bool FunctionalTest::isStencilType(TextureInternalFormatDescriptor descriptor)
   1047 {
   1048 	return (descriptor.min_stencil_size > 0);
   1049 }
   1050 
   1051 bool FunctionalTest::isChannelTypeNone(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel)
   1052 {
   1053 	switch (channel)
   1054 	{
   1055 	case RED_COMPONENT:
   1056 		return (GL_NONE == descriptor.expected_red_type);
   1057 	case GREEN_COMPONENT:
   1058 		return (GL_NONE == descriptor.expected_green_type);
   1059 	case BLUE_COMPONENT:
   1060 		return (GL_NONE == descriptor.expected_blue_type);
   1061 	case ALPHA_COMPONENT:
   1062 		return (GL_NONE == descriptor.expected_alpha_type);
   1063 	default:
   1064 		throw 0;
   1065 	}
   1066 
   1067 	return false;
   1068 }
   1069 
   1070 glw::GLfloat FunctionalTest::getMinPrecision(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel)
   1071 {
   1072 	/* Select channel data. */
   1073 	glw::GLenum type = GL_NONE;
   1074 	glw::GLuint size = 0;
   1075 
   1076 	switch (channel)
   1077 	{
   1078 	case RED_COMPONENT:
   1079 		type = descriptor.expected_red_type;
   1080 		size = descriptor.min_red_size;
   1081 		break;
   1082 	case GREEN_COMPONENT:
   1083 		type = descriptor.expected_green_type;
   1084 		size = descriptor.min_green_size;
   1085 		break;
   1086 	case BLUE_COMPONENT:
   1087 		type = descriptor.expected_blue_type;
   1088 		size = descriptor.min_blue_size;
   1089 		break;
   1090 	case ALPHA_COMPONENT:
   1091 		type = descriptor.expected_alpha_type;
   1092 		size = descriptor.min_alpha_size;
   1093 		break;
   1094 	default:
   1095 		throw 0;
   1096 	}
   1097 
   1098 	/* If it is empty channel. */
   1099 	if ((type == GL_NONE) || (size == 0))
   1100 	{
   1101 		return 0.1f;
   1102 	}
   1103 
   1104 	/* If float type. */
   1105 	if (isFloatType(descriptor))
   1106 	{
   1107 		switch (size)
   1108 		{
   1109 		case 32:
   1110 			return 0.00001f; /* specification GL4.5 core constant */
   1111 		case 16:
   1112 			return 1.f / 1024.f; /* specification GL4.5 core 10 bit mantisa constant */
   1113 		case 11:
   1114 			return 1.f / 64.f; /* specification GL4.5 core 6 bit mantisa constant */
   1115 		case 10:
   1116 			return 1.f / 32.f; /* specification GL4.5 core 5 bit mantisa constant */
   1117 		default:
   1118 			return 0.00001f;
   1119 		}
   1120 	}
   1121 
   1122 	/* Fixed types precision */
   1123 	if (isFixedSignedType(descriptor))
   1124 	{
   1125 		return (float)(1.0 / pow(2.0, (double)(size - 1 /* sign bit */)));
   1126 	}
   1127 
   1128 	if (isFixedUnsignedType(descriptor))
   1129 	{
   1130 		return (float)(1.0 / pow(2.0, (double)(size)));
   1131 	}
   1132 
   1133 	/* other aka (unsigned) integer */
   1134 	return 1;
   1135 }
   1136 
   1137 bool FunctionalTest::isTargetMultisampled(glw::GLenum target)
   1138 {
   1139 	return (GL_TEXTURE_2D_MULTISAMPLE == target) || (GL_TEXTURE_2D_MULTISAMPLE_ARRAY == target);
   1140 }
   1141 
   1142 float FunctionalTest::convert_from_sRGB(float value)
   1143 {
   1144 	/* For reference check OpenGL specification (eg. OpenGL 4.5 core profile specification chapter 8.24 */
   1145 	if (value > 0.04045f)
   1146 	{
   1147 		return deFloatPow((value + 0.055f) / 1.055f, 2.4f);
   1148 	}
   1149 
   1150 	return value / 12.92f;
   1151 }
   1152 
   1153 const glw::GLfloat FunctionalTest::s_source_texture_data_f[] = { 0.125f, 0.25f, 0.5f, 0.75f };
   1154 
   1155 const glw::GLfloat FunctionalTest::s_source_texture_data_n[] = { 0.125f, 0.25f, 0.5f, 0.75f };
   1156 
   1157 const glw::GLfloat FunctionalTest::s_source_texture_data_sn[] = { -0.125f, 0.25f, -0.5f, 0.75f };
   1158 
   1159 const glw::GLint FunctionalTest::s_source_texture_data_i[] = { -1, 2, -3, 4 };
   1160 
   1161 const glw::GLuint FunctionalTest::s_source_texture_data_ui[] = { 4, 3, 2, 1 };
   1162 
   1163 const glw::GLfloat FunctionalTest::s_destination_texture_data_f[] = {
   1164 	5.f
   1165 }; /* False data for destination texture to be overwriten. */
   1166 
   1167 const glw::GLint FunctionalTest::s_destination_texture_data_i[] = {
   1168 	-5
   1169 }; /* False data for destination texture to be overwriten. */
   1170 
   1171 const glw::GLuint FunctionalTest::s_destination_texture_data_ui[] = {
   1172 	5
   1173 }; /* False data for destination texture to be overwriten. */
   1174 
   1175 const glw::GLenum FunctionalTest::s_source_texture_targets[] = {
   1176 	GL_TEXTURE_1D,		 GL_TEXTURE_2D, GL_TEXTURE_1D_ARRAY,	   GL_TEXTURE_RECTANGLE,
   1177 	GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY
   1178 };
   1179 
   1180 const glw::GLchar* FunctionalTest::s_source_texture_targets_names[] = {
   1181 	STR(GL_TEXTURE_1D),		  STR(GL_TEXTURE_2D), STR(GL_TEXTURE_1D_ARRAY),		  STR(GL_TEXTURE_RECTANGLE),
   1182 	STR(GL_TEXTURE_2D_ARRAY), STR(GL_TEXTURE_3D), STR(GL_TEXTURE_2D_MULTISAMPLE), STR(GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
   1183 };
   1184 
   1185 const glw::GLuint FunctionalTest::s_source_texture_targets_count =
   1186 	sizeof(s_source_texture_targets) / sizeof(s_source_texture_targets[0]);
   1187 
   1188 const glw::GLuint FunctionalTest::s_source_texture_size = 1;
   1189 
   1190 const glw::GLchar* FunctionalTest::s_color_channel_names[] = { "red", "green", "blue", "alpha", "all" };
   1191 
   1192 const FunctionalTest::TextureInternalFormatDescriptor FunctionalTest::s_formats[] = {
   1193 	/*	context version,							internal format,		internal format name,	 is sRGB,	CR,size{R,	G,	B,	A,	D,	S},	type of R,				type of G,				type of B,				type of A,				type of depth			*/
   1194 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R8, STR(GL_R8), false, true, 8, 0, 0, 0, 0, 0,
   1195 	  GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1196 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_R8_SNORM, STR(GL_R8_SNORM), false, true, 8, 0, 0, 0, 0, 0,
   1197 	  GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1198 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16, STR(GL_R16), false, true, 16, 0, 0, 0, 0, 0,
   1199 	  GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1200 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_R16_SNORM, STR(GL_R16_SNORM), false, true, 16, 0, 0, 0, 0, 0,
   1201 	  GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1202 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG8, STR(GL_RG8), false, true, 8, 8, 0, 0, 0, 0,
   1203 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
   1204 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RG8_SNORM, STR(GL_RG8_SNORM), false, true, 8, 8, 0, 0, 0, 0,
   1205 	  GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
   1206 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16, STR(GL_RG16), false, true, 16, 16, 0, 0, 0, 0,
   1207 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
   1208 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RG16_SNORM, STR(GL_RG16_SNORM), false, true, 16, 16, 0, 0, 0, 0,
   1209 	  GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE, GL_NONE },
   1210 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_R3_G3_B2, STR(GL_R3_G3_B2), false, true, 3, 3, 2, 0, 0, 0,
   1211 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1212 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB4, STR(GL_RGB4), false, true, 4, 4, 4, 0, 0, 0,
   1213 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1214 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB5, STR(GL_RGB5), false, true, 5, 5, 5, 0, 0, 0,
   1215 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1216 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB8, STR(GL_RGB8), false, true, 8, 8, 8, 0, 0, 0,
   1217 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1218 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGB8_SNORM, STR(GL_RGB8_SNORM), false, true, 8, 8, 8, 0, 0, 0,
   1219 	  GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1220 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB10, STR(GL_RGB10), false, true, 10, 10, 10, 0, 0, 0,
   1221 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1222 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGB12, STR(GL_RGB12), false, true, 12, 12, 12, 0, 0, 0,
   1223 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1224 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16, STR(GL_RGB16), false, true, 16, 16, 16, 0, 0, 0,
   1225 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1226 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGB16_SNORM, STR(GL_RGB16_SNORM), false, true, 16, 16, 16, 0, 0, 0,
   1227 	  GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1228 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGBA2, STR(GL_RGBA2), false, true, 2, 2, 2, 2, 0, 0,
   1229 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1230 	{ glu::ContextType(4, 2, glu::PROFILE_CORE), GL_RGBA4, STR(GL_RGBA4), false, true, 4, 4, 4, 4, 0, 0,
   1231 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1232 	{ glu::ContextType(4, 2, glu::PROFILE_CORE), GL_RGB5_A1, STR(GL_RGB5_A1), false, true, 5, 5, 5, 1, 0, 0,
   1233 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1234 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA8, STR(GL_RGBA8), false, true, 8, 8, 8, 8, 0, 0,
   1235 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1236 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGBA8_SNORM, STR(GL_RGBA8_SNORM), false, true, 8, 8, 8, 8, 0, 0,
   1237 	  GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE },
   1238 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB10_A2, STR(GL_RGB10_A2), false, true, 10, 10, 10, 2, 0, 0,
   1239 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1240 	{ glu::ContextType(3, 3, glu::PROFILE_CORE), GL_RGB10_A2UI, STR(GL_RGB10_A2UI), false, true, 10, 10, 10, 2, 0, 0,
   1241 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
   1242 	{ glu::ContextType(4, 4, glu::PROFILE_CORE), GL_RGBA12, STR(GL_RGBA12), false, true, 12, 12, 12, 12, 0, 0,
   1243 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1244 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16, STR(GL_RGBA16), false, true, 16, 16, 16, 16, 0, 0,
   1245 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1246 	{ glu::ContextType(3, 1, glu::PROFILE_CORE), GL_RGBA16_SNORM, STR(GL_RGBA16_SNORM), false, true, 16, 16, 16, 16, 0,
   1247 	  0, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, GL_NONE },
   1248 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_SRGB8, STR(GL_SRGB8), true, true, 8, 8, 8, 0, 0, 0,
   1249 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE, GL_NONE },
   1250 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_SRGB8_ALPHA8, STR(GL_SRGB8_ALPHA8), true, true, 8, 8, 8, 8, 0, 0,
   1251 	  GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_UNSIGNED_NORMALIZED, GL_NONE },
   1252 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16F, STR(GL_R16F), false, true, 16, 0, 0, 0, 0, 0, GL_FLOAT,
   1253 	  GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1254 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16F, STR(GL_RG16F), false, true, 16, 16, 0, 0, 0, 0, GL_FLOAT,
   1255 	  GL_FLOAT, GL_NONE, GL_NONE, GL_NONE },
   1256 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16F, STR(GL_RGB16F), false, true, 16, 16, 16, 0, 0, 0, GL_FLOAT,
   1257 	  GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
   1258 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16F, STR(GL_RGBA16F), false, true, 16, 16, 16, 16, 0, 0,
   1259 	  GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_NONE },
   1260 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R32F, STR(GL_R32F), false, true, 32, 0, 0, 0, 0, 0, GL_FLOAT,
   1261 	  GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1262 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG32F, STR(GL_RG32F), false, true, 32, 32, 0, 0, 0, 0, GL_FLOAT,
   1263 	  GL_FLOAT, GL_NONE, GL_NONE, GL_NONE },
   1264 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB32F, STR(GL_RGB32F), false, true, 32, 32, 32, 0, 0, 0, GL_FLOAT,
   1265 	  GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
   1266 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA32F, STR(GL_RGBA32F), false, true, 32, 32, 32, 32, 0, 0,
   1267 	  GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_NONE },
   1268 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R11F_G11F_B10F, STR(GL_R11F_G11F_B10F), false, true, 11, 11, 10, 0,
   1269 	  0, 0, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
   1270 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB9_E5, STR(GL_RGB9_E5), false, false, 9, 9, 9, 0, 0, 0, GL_FLOAT,
   1271 	  GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE },
   1272 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R8I, STR(GL_R8I), false, true, 8, 0, 0, 0, 0, 0, GL_INT, GL_NONE,
   1273 	  GL_NONE, GL_NONE, GL_NONE },
   1274 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R8UI, STR(GL_R8UI), false, true, 8, 0, 0, 0, 0, 0, GL_UNSIGNED_INT,
   1275 	  GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1276 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16I, STR(GL_R16I), false, true, 16, 0, 0, 0, 0, 0, GL_INT, GL_NONE,
   1277 	  GL_NONE, GL_NONE, GL_NONE },
   1278 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R16UI, STR(GL_R16UI), false, true, 16, 0, 0, 0, 0, 0,
   1279 	  GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1280 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R32I, STR(GL_R32I), false, true, 32, 0, 0, 0, 0, 0, GL_INT, GL_NONE,
   1281 	  GL_NONE, GL_NONE, GL_NONE },
   1282 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_R32UI, STR(GL_R32UI), false, true, 32, 0, 0, 0, 0, 0,
   1283 	  GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE, GL_NONE },
   1284 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG8I, STR(GL_RG8I), false, true, 8, 8, 0, 0, 0, 0, GL_INT, GL_INT,
   1285 	  GL_NONE, GL_NONE, GL_NONE },
   1286 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG8UI, STR(GL_RG8UI), false, true, 8, 8, 0, 0, 0, 0,
   1287 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE },
   1288 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16I, STR(GL_RG16I), false, true, 16, 16, 0, 0, 0, 0, GL_INT,
   1289 	  GL_INT, GL_NONE, GL_NONE, GL_NONE },
   1290 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG16UI, STR(GL_RG16UI), false, true, 16, 16, 0, 0, 0, 0,
   1291 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE },
   1292 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG32I, STR(GL_RG32I), false, true, 32, 32, 0, 0, 0, 0, GL_INT,
   1293 	  GL_INT, GL_NONE, GL_NONE, GL_NONE },
   1294 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RG32UI, STR(GL_RG32UI), false, true, 32, 32, 0, 0, 0, 0,
   1295 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE },
   1296 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB8I, STR(GL_RGB8I), false, true, 8, 8, 8, 0, 0, 0, GL_INT, GL_INT,
   1297 	  GL_INT, GL_NONE, GL_NONE },
   1298 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB8UI, STR(GL_RGB8UI), false, true, 8, 8, 8, 0, 0, 0,
   1299 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE },
   1300 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16I, STR(GL_RGB16I), false, true, 16, 16, 16, 0, 0, 0, GL_INT,
   1301 	  GL_INT, GL_INT, GL_NONE, GL_NONE },
   1302 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB16UI, STR(GL_RGB16UI), false, true, 16, 16, 16, 0, 0, 0,
   1303 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE },
   1304 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB32I, STR(GL_RGB32I), false, true, 32, 32, 32, 0, 0, 0, GL_INT,
   1305 	  GL_INT, GL_INT, GL_NONE, GL_NONE },
   1306 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGB32UI, STR(GL_RGB32UI), false, true, 32, 32, 32, 0, 0, 0,
   1307 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE },
   1308 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA8I, STR(GL_RGBA8I), false, true, 8, 8, 8, 8, 0, 0, GL_INT,
   1309 	  GL_INT, GL_INT, GL_INT, GL_NONE },
   1310 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA8UI, STR(GL_RGBA8UI), false, true, 8, 8, 8, 8, 0, 0,
   1311 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
   1312 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16I, STR(GL_RGBA16I), false, true, 16, 16, 16, 16, 0, 0, GL_INT,
   1313 	  GL_INT, GL_INT, GL_INT, GL_NONE },
   1314 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA16UI, STR(GL_RGBA16UI), false, true, 16, 16, 16, 16, 0, 0,
   1315 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
   1316 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA32I, STR(GL_RGBA32I), false, true, 32, 32, 32, 32, 0, 0, GL_INT,
   1317 	  GL_INT, GL_INT, GL_INT, GL_NONE },
   1318 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_RGBA32UI, STR(GL_RGBA32UI), false, true, 32, 32, 32, 32, 0, 0,
   1319 	  GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE },
   1320 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH_COMPONENT16, STR(GL_DEPTH_COMPONENT16), false, true, 0, 0, 0,
   1321 	  0, 16, 0, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_UNSIGNED_NORMALIZED },
   1322 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH_COMPONENT24, STR(GL_DEPTH_COMPONENT24), false, true, 0, 0, 0,
   1323 	  0, 24, 0, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_UNSIGNED_NORMALIZED },
   1324 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH_COMPONENT32F, STR(GL_DEPTH_COMPONENT32F), false, true, 0, 0,
   1325 	  0, 0, 32, 0, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_FLOAT },
   1326 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH24_STENCIL8, STR(GL_DEPTH24_STENCIL8), false, true, 0, 0, 0, 0,
   1327 	  24, 8, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_UNSIGNED_NORMALIZED },
   1328 	{ glu::ContextType(3, 0, glu::PROFILE_CORE), GL_DEPTH32F_STENCIL8, STR(GL_DEPTH32F_STENCIL8), false, true, 0, 0, 0,
   1329 	  0, 32, 8, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_FLOAT }
   1330 };
   1331 
   1332 const glw::GLuint FunctionalTest::s_formats_size = sizeof(s_formats) / sizeof(s_formats[0]);
   1333 
   1334 const glw::GLchar* FunctionalTest::s_vertex_shader_code = "#version 150\n"
   1335 														  "\n"
   1336 														  "void main()\n"
   1337 														  "{\n"
   1338 														  "    switch(gl_VertexID % 4)\n"
   1339 														  "    {\n"
   1340 														  "    case 0:\n"
   1341 														  "        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   1342 														  "        break;\n"
   1343 														  "    case 1:\n"
   1344 														  "        gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   1345 														  "        break;\n"
   1346 														  "    case 2:\n"
   1347 														  "        gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   1348 														  "        break;\n"
   1349 														  "    case 3:\n"
   1350 														  "        gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   1351 														  "        break;\n"
   1352 														  "    }\n"
   1353 														  "}\n";
   1354 
   1355 const glw::GLchar* FunctionalTest::s_fragment_shader_template =
   1356 	"#version 150\n"
   1357 	"\n"
   1358 	"out TEMPLATE_TYPE result;\n"
   1359 	"\n"
   1360 	"uniform TEMPLATE_SAMPLER data;\n"
   1361 	"\n"
   1362 	"void main()\n"
   1363 	"{\n"
   1364 	"    result = texelFetch(data, TEMPLATE_TEXEL_FETCH_ARGUMENTS)TEMPLATE_COMPONENT;\n"
   1365 	"}\n";
   1366 
   1367 /*===========================================================================================================*/
   1368 
   1369 namespace Utilities
   1370 {
   1371 
   1372 glw::GLuint buildProgram(glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const vertex_shader_source,
   1373 						 glw::GLchar const* const fragment_shader_source)
   1374 {
   1375 	glw::GLuint program = 0;
   1376 
   1377 	struct Shader
   1378 	{
   1379 		glw::GLchar const* const source;
   1380 		glw::GLenum const		 type;
   1381 		glw::GLuint				 id;
   1382 	} shader[] = { { vertex_shader_source, GL_VERTEX_SHADER, 0 }, { fragment_shader_source, GL_FRAGMENT_SHADER, 0 } };
   1383 
   1384 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   1385 
   1386 	try
   1387 	{
   1388 		/* Create program. */
   1389 		program = gl.createProgram();
   1390 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   1391 
   1392 		/* Shader compilation. */
   1393 
   1394 		for (glw::GLuint i = 0; i < shader_count; ++i)
   1395 		{
   1396 			if (DE_NULL != shader[i].source)
   1397 			{
   1398 				shader[i].id = gl.createShader(shader[i].type);
   1399 
   1400 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   1401 
   1402 				gl.attachShader(program, shader[i].id);
   1403 
   1404 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   1405 
   1406 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   1407 
   1408 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   1409 
   1410 				gl.compileShader(shader[i].id);
   1411 
   1412 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   1413 
   1414 				glw::GLint status = GL_FALSE;
   1415 
   1416 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   1417 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1418 
   1419 				if (GL_FALSE == status)
   1420 				{
   1421 					glw::GLint log_size = 0;
   1422 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   1423 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1424 
   1425 					glw::GLchar* log_text = new glw::GLchar[log_size];
   1426 
   1427 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   1428 
   1429 					log << tcu::TestLog::Message << "Shader compilation has failed.\n"
   1430 						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
   1431 						<< "Shader compilation error log:\n"
   1432 						<< log_text << "\n"
   1433 						<< "Shader source code:\n"
   1434 						<< shader[i].source << "\n"
   1435 						<< tcu::TestLog::EndMessage;
   1436 
   1437 					delete[] log_text;
   1438 
   1439 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   1440 
   1441 					throw 0;
   1442 				}
   1443 			}
   1444 		}
   1445 
   1446 		/* Link. */
   1447 		gl.linkProgram(program);
   1448 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   1449 
   1450 		glw::GLint status = GL_FALSE;
   1451 
   1452 		gl.getProgramiv(program, GL_LINK_STATUS, &status);
   1453 
   1454 		if (GL_TRUE == status)
   1455 		{
   1456 			for (glw::GLuint i = 0; i < shader_count; ++i)
   1457 			{
   1458 				if (shader[i].id)
   1459 				{
   1460 					gl.detachShader(program, shader[i].id);
   1461 
   1462 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   1463 				}
   1464 			}
   1465 		}
   1466 		else
   1467 		{
   1468 			glw::GLint log_size = 0;
   1469 
   1470 			gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &log_size);
   1471 
   1472 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   1473 
   1474 			glw::GLchar* log_text = new glw::GLchar[log_size];
   1475 
   1476 			gl.getProgramInfoLog(program, log_size, NULL, &log_text[0]);
   1477 
   1478 			log << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   1479 				<< log_text << "\n"
   1480 				<< tcu::TestLog::EndMessage;
   1481 
   1482 			delete[] log_text;
   1483 
   1484 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   1485 
   1486 			throw 0;
   1487 		}
   1488 	}
   1489 	catch (...)
   1490 	{
   1491 		if (program)
   1492 		{
   1493 			gl.deleteProgram(program);
   1494 
   1495 			program = 0;
   1496 		}
   1497 	}
   1498 
   1499 	for (glw::GLuint i = 0; i < shader_count; ++i)
   1500 	{
   1501 		if (0 != shader[i].id)
   1502 		{
   1503 			gl.deleteShader(shader[i].id);
   1504 
   1505 			shader[i].id = 0;
   1506 		}
   1507 	}
   1508 
   1509 	return program;
   1510 }
   1511 
   1512 std::string preprocessString(std::string source, std::string key, std::string value)
   1513 {
   1514 	std::string destination = source;
   1515 
   1516 	while (true)
   1517 	{
   1518 		/* Find token in source code. */
   1519 		size_t position = destination.find(key, 0);
   1520 
   1521 		/* No more occurences of this key. */
   1522 		if (position == std::string::npos)
   1523 		{
   1524 			break;
   1525 		}
   1526 
   1527 		/* Replace token with sub_code. */
   1528 		destination.replace(position, key.size(), value);
   1529 	}
   1530 
   1531 	return destination;
   1532 }
   1533 
   1534 std::string itoa(glw::GLint i)
   1535 {
   1536 	std::stringstream stream;
   1537 
   1538 	stream << i;
   1539 
   1540 	return stream.str();
   1541 }
   1542 
   1543 } // namespace Utilities
   1544 } // namespace TextureSizePromotion
   1545 } // namespace gl3cts
   1546