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