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