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