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 						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 
prepareVertexArrayObject()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 
prepareSourceTexture(TextureInternalFormatDescriptor descriptor,glw::GLenum target)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 
renderDataIntoMultisampledTexture(TextureInternalFormatDescriptor descriptor,glw::GLenum target)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 
prepareDestinationTextureAndFramebuffer(TextureInternalFormatDescriptor descriptor,glw::GLenum target)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 
makeProgramAndSourceTextureActive(glw::GLenum target)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 
checkSourceTextureSizeAndType(TextureInternalFormatDescriptor descriptor,glw::GLenum target)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 
getDestinationFormatForChannel(TextureInternalFormatDescriptor descriptor)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 
prepareProgram(glw::GLenum target,TextureInternalFormatDescriptor descriptor,ColorChannelSelector channel)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 
drawQuad()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 
cleanSourceTexture()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 
cleanDestinationTexture()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 
cleanFramebuffer()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 
cleanProgram()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 
cleanVertexArrayObject()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 
checkDestinationTexture(TextureInternalFormatDescriptor descriptor,ColorChannelSelector channel,glw::GLenum target,const glw::GLchar * target_name)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 
isFloatType(TextureInternalFormatDescriptor descriptor)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 
isFixedSignedType(TextureInternalFormatDescriptor descriptor)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 
isFixedUnsignedType(TextureInternalFormatDescriptor descriptor)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 
isIntegerSignedType(TextureInternalFormatDescriptor descriptor)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 
isIntegerUnsignedType(TextureInternalFormatDescriptor descriptor)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 
isDepthType(TextureInternalFormatDescriptor descriptor)1041 bool FunctionalTest::isDepthType(TextureInternalFormatDescriptor descriptor)
1042 {
1043 	return (GL_NONE != descriptor.expected_depth_type);
1044 }
1045 
isStencilType(TextureInternalFormatDescriptor descriptor)1046 bool FunctionalTest::isStencilType(TextureInternalFormatDescriptor descriptor)
1047 {
1048 	return (descriptor.min_stencil_size > 0);
1049 }
1050 
isChannelTypeNone(TextureInternalFormatDescriptor descriptor,ColorChannelSelector channel)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 
getMinPrecision(TextureInternalFormatDescriptor descriptor,ColorChannelSelector channel)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 
isTargetMultisampled(glw::GLenum target)1137 bool FunctionalTest::isTargetMultisampled(glw::GLenum target)
1138 {
1139 	return (GL_TEXTURE_2D_MULTISAMPLE == target) || (GL_TEXTURE_2D_MULTISAMPLE_ARRAY == target);
1140 }
1141 
convert_from_sRGB(float value)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 
buildProgram(glw::Functions const & gl,tcu::TestLog & log,glw::GLchar const * const vertex_shader_source,glw::GLchar const * const fragment_shader_source)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 
preprocessString(std::string source,std::string key,std::string value)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 
itoa(glw::GLint i)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