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