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