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