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