1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 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 Copy image tests for GL_EXT_copy_image. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fCopyImageTests.hpp" 25 26 #include "tes31TestCase.hpp" 27 28 #include "glsTextureTestUtil.hpp" 29 30 #include "gluContextInfo.hpp" 31 #include "gluObjectWrapper.hpp" 32 #include "gluRenderContext.hpp" 33 #include "gluStrUtil.hpp" 34 #include "gluTextureUtil.hpp" 35 #include "gluPixelTransfer.hpp" 36 37 #include "glwEnums.hpp" 38 #include "glwFunctions.hpp" 39 40 #include "tcuCompressedTexture.hpp" 41 #include "tcuFloat.hpp" 42 #include "tcuImageCompare.hpp" 43 #include "tcuTestLog.hpp" 44 #include "tcuTexture.hpp" 45 #include "tcuTextureUtil.hpp" 46 #include "tcuVector.hpp" 47 #include "tcuVectorUtil.hpp" 48 #include "tcuSeedBuilder.hpp" 49 #include "tcuResultCollector.hpp" 50 51 #include "deArrayBuffer.hpp" 52 #include "deFloat16.h" 53 #include "deRandom.hpp" 54 #include "deStringUtil.hpp" 55 #include "deUniquePtr.hpp" 56 #include "deArrayUtil.hpp" 57 58 #include <map> 59 #include <string> 60 #include <vector> 61 62 using namespace deqp::gls::TextureTestUtil; 63 using namespace glu::TextureTestUtil; 64 65 using tcu::Float; 66 using tcu::IVec2; 67 using tcu::IVec3; 68 using tcu::IVec4; 69 using tcu::Sampler; 70 using tcu::ScopedLogSection; 71 using tcu::TestLog; 72 using tcu::Vec4; 73 using tcu::SeedBuilder; 74 75 using de::ArrayBuffer; 76 77 using std::map; 78 using std::string; 79 using std::vector; 80 using std::pair; 81 82 namespace deqp 83 { 84 namespace gles31 85 { 86 namespace Functional 87 { 88 namespace 89 { 90 91 enum ViewClass 92 { 93 VIEWCLASS_128_BITS = 0, 94 VIEWCLASS_96_BITS, 95 VIEWCLASS_64_BITS, 96 VIEWCLASS_48_BITS, 97 VIEWCLASS_32_BITS, 98 VIEWCLASS_24_BITS, 99 VIEWCLASS_16_BITS, 100 VIEWCLASS_8_BITS, 101 102 VIEWCLASS_EAC_R11, 103 VIEWCLASS_EAC_RG11, 104 VIEWCLASS_ETC2_RGB, 105 VIEWCLASS_ETC2_RGBA, 106 VIEWCLASS_ETC2_EAC_RGBA, 107 VIEWCLASS_ASTC_4x4_RGBA, 108 VIEWCLASS_ASTC_5x4_RGBA, 109 VIEWCLASS_ASTC_5x5_RGBA, 110 VIEWCLASS_ASTC_6x5_RGBA, 111 VIEWCLASS_ASTC_6x6_RGBA, 112 VIEWCLASS_ASTC_8x5_RGBA, 113 VIEWCLASS_ASTC_8x6_RGBA, 114 VIEWCLASS_ASTC_8x8_RGBA, 115 VIEWCLASS_ASTC_10x5_RGBA, 116 VIEWCLASS_ASTC_10x6_RGBA, 117 VIEWCLASS_ASTC_10x8_RGBA, 118 VIEWCLASS_ASTC_10x10_RGBA, 119 VIEWCLASS_ASTC_12x10_RGBA, 120 VIEWCLASS_ASTC_12x12_RGBA 121 }; 122 123 enum Verify 124 { 125 VERIFY_NONE = 0, 126 VERIFY_COMPARE_REFERENCE 127 }; 128 129 const char* viewClassToName (ViewClass viewClass) 130 { 131 switch (viewClass) 132 { 133 case VIEWCLASS_128_BITS: return "viewclass_128_bits"; 134 case VIEWCLASS_96_BITS: return "viewclass_96_bits"; 135 case VIEWCLASS_64_BITS: return "viewclass_64_bits"; 136 case VIEWCLASS_48_BITS: return "viewclass_48_bits"; 137 case VIEWCLASS_32_BITS: return "viewclass_32_bits"; 138 case VIEWCLASS_24_BITS: return "viewclass_24_bits"; 139 case VIEWCLASS_16_BITS: return "viewclass_16_bits"; 140 case VIEWCLASS_8_BITS: return "viewclass_8_bits"; 141 case VIEWCLASS_EAC_R11: return "viewclass_eac_r11"; 142 case VIEWCLASS_EAC_RG11: return "viewclass_eac_rg11"; 143 case VIEWCLASS_ETC2_RGB: return "viewclass_etc2_rgb"; 144 case VIEWCLASS_ETC2_RGBA: return "viewclass_etc2_rgba"; 145 case VIEWCLASS_ETC2_EAC_RGBA: return "viewclass_etc2_eac_rgba"; 146 case VIEWCLASS_ASTC_4x4_RGBA: return "viewclass_astc_4x4_rgba"; 147 case VIEWCLASS_ASTC_5x4_RGBA: return "viewclass_astc_5x4_rgba"; 148 case VIEWCLASS_ASTC_5x5_RGBA: return "viewclass_astc_5x5_rgba"; 149 case VIEWCLASS_ASTC_6x5_RGBA: return "viewclass_astc_6x5_rgba"; 150 case VIEWCLASS_ASTC_6x6_RGBA: return "viewclass_astc_6x6_rgba"; 151 case VIEWCLASS_ASTC_8x5_RGBA: return "viewclass_astc_8x5_rgba"; 152 case VIEWCLASS_ASTC_8x6_RGBA: return "viewclass_astc_8x6_rgba"; 153 case VIEWCLASS_ASTC_8x8_RGBA: return "viewclass_astc_8x8_rgba"; 154 case VIEWCLASS_ASTC_10x5_RGBA: return "viewclass_astc_10x5_rgba"; 155 case VIEWCLASS_ASTC_10x6_RGBA: return "viewclass_astc_10x6_rgba"; 156 case VIEWCLASS_ASTC_10x8_RGBA: return "viewclass_astc_10x8_rgba"; 157 case VIEWCLASS_ASTC_10x10_RGBA: return "viewclass_astc_10x10_rgba"; 158 case VIEWCLASS_ASTC_12x10_RGBA: return "viewclass_astc_12x10_rgba"; 159 case VIEWCLASS_ASTC_12x12_RGBA: return "viewclass_astc_12x12_rgba"; 160 161 default: 162 DE_ASSERT(false); 163 return NULL; 164 } 165 } 166 167 const char* targetToName (deUint32 target) 168 { 169 switch (target) 170 { 171 case GL_RENDERBUFFER: return "renderbuffer"; 172 case GL_TEXTURE_2D: return "texture2d"; 173 case GL_TEXTURE_3D: return "texture3d"; 174 case GL_TEXTURE_2D_ARRAY: return "texture2d_array"; 175 case GL_TEXTURE_CUBE_MAP: return "cubemap"; 176 177 default: 178 DE_ASSERT(false); 179 return NULL; 180 } 181 } 182 183 string formatToName (deUint32 format) 184 { 185 string enumName; 186 187 if (glu::isCompressedFormat(format)) 188 enumName = glu::getCompressedTextureFormatStr(format).toString().substr(14); // Strip GL_COMPRESSED_ 189 else 190 enumName = glu::getUncompressedTextureFormatStr(format).toString().substr(3); // Strip GL_ 191 192 return de::toLower(enumName); 193 } 194 195 bool isFloatFormat (deUint32 format) 196 { 197 if (glu::isCompressedFormat(format)) 198 return false; 199 else 200 return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT; 201 } 202 203 bool isUintFormat (deUint32 format) 204 { 205 if (glu::isCompressedFormat(format)) 206 return false; 207 else 208 return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER; 209 } 210 211 bool isIntFormat (deUint32 format) 212 { 213 if (glu::isCompressedFormat(format)) 214 return false; 215 else 216 return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER; 217 } 218 219 bool isFixedPointFormat (deUint32 format) 220 { 221 if (glu::isCompressedFormat(format)) 222 return false; 223 else 224 { 225 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type); 226 227 return channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; 228 } 229 } 230 231 bool isTextureTarget (deUint32 target) 232 { 233 return target != GL_RENDERBUFFER; 234 } 235 236 int getTargetTexDims (deUint32 target) 237 { 238 DE_ASSERT(isTextureTarget(target)); 239 240 switch (target) 241 { 242 case GL_TEXTURE_1D: 243 return 1; 244 245 case GL_TEXTURE_1D_ARRAY: 246 case GL_TEXTURE_2D: 247 case GL_TEXTURE_CUBE_MAP: 248 return 2; 249 250 case GL_TEXTURE_2D_ARRAY: 251 case GL_TEXTURE_3D: 252 return 3; 253 254 default: 255 DE_ASSERT(false); 256 return -1; 257 } 258 } 259 260 class RandomizedRenderGrid 261 { 262 public: 263 RandomizedRenderGrid (const IVec2& targetSize, const IVec2& cellSize, int maxCellCount, deUint32 seed); 264 bool nextCell (void); 265 IVec2 getOrigin (void) const; 266 267 const IVec2& getCellSize (void) const { return m_cellSize; }; 268 IVec4 getUsedAreaBoundingBox (void) const; 269 int getCellCount (void) const { return m_cellCount; }; 270 271 private: 272 static IVec2 getRandomOffset (deUint32 seed, IVec2 targetSize, IVec2 cellSize, IVec2 grid, int cellCount); 273 274 const IVec2 m_targetSize; 275 const IVec2 m_cellSize; 276 const IVec2 m_grid; 277 int m_currentCell; 278 const int m_cellCount; 279 const IVec2 m_baseRandomOffset; 280 }; 281 282 RandomizedRenderGrid::RandomizedRenderGrid (const IVec2& targetSize, const IVec2& cellSize, int maxCellCount, deUint32 seed) 283 : m_targetSize (targetSize) 284 , m_cellSize (cellSize) 285 , m_grid (targetSize / cellSize) 286 , m_currentCell (0) 287 // If the grid exactly fits height, take one row for randomization. 288 , m_cellCount (deMin32(maxCellCount, ((targetSize.y() % cellSize.y()) == 0) && m_grid.y() > 1 ? m_grid.x() * (m_grid.y() - 1) : m_grid.x() * m_grid.y())) 289 , m_baseRandomOffset (getRandomOffset(seed, targetSize, cellSize, m_grid, m_cellCount)) 290 { 291 } 292 293 IVec2 RandomizedRenderGrid::getRandomOffset (deUint32 seed, IVec2 targetSize, IVec2 cellSize, IVec2 grid, int cellCount) 294 { 295 de::Random rng (seed); 296 IVec2 result; 297 IVec2 extraSpace = targetSize - (cellSize * grid); 298 299 // If there'll be unused rows, donate them into extra space. 300 // (Round the required rows to full cell row to find out how many rows are unused, multiply by size) 301 DE_ASSERT(deDivRoundUp32(cellCount, grid.x()) <= grid.y()); 302 extraSpace.y() += (grid.y() - deDivRoundUp32(cellCount, grid.x())) * cellSize.y(); 303 304 DE_ASSERT(targetSize.x() > cellSize.x() && targetSize.y() > cellSize.y()); 305 // If grid fits perfectly just one row of cells, just give up on randomizing. 306 DE_ASSERT(extraSpace.x() > 0 || extraSpace.y() > 0 || grid.y() == 1); 307 DE_ASSERT(extraSpace.x() + grid.x() * cellSize.x() == targetSize.x()); 308 309 // \note Putting these as ctor params would make evaluation order undefined, I think <sigh>. Hence, 310 // no direct return. 311 result.x() = rng.getInt(0, extraSpace.x()); 312 result.y() = rng.getInt(0, extraSpace.y()); 313 return result; 314 } 315 316 bool RandomizedRenderGrid::nextCell (void) 317 { 318 if (m_currentCell >= getCellCount()) 319 return false; 320 321 m_currentCell++; 322 return true; 323 } 324 325 IVec2 RandomizedRenderGrid::getOrigin (void) const 326 { 327 const int gridX = (m_currentCell - 1) % m_grid.x(); 328 const int gridY = (m_currentCell - 1) / m_grid.x(); 329 const IVec2 currentOrigin = (IVec2(gridX, gridY) * m_cellSize) + m_baseRandomOffset; 330 331 DE_ASSERT(currentOrigin.x() >= 0 && (currentOrigin.x() + m_cellSize.x()) <= m_targetSize.x()); 332 DE_ASSERT(currentOrigin.y() >= 0 && (currentOrigin.y() + m_cellSize.y()) <= m_targetSize.y()); 333 334 return currentOrigin; 335 } 336 337 IVec4 RandomizedRenderGrid::getUsedAreaBoundingBox (void) const 338 { 339 const IVec2 lastCell (de::min(m_currentCell + 1, m_grid.x()), ((m_currentCell + m_grid.x() - 1) / m_grid.x())); 340 const IVec2 size = lastCell * m_cellSize; 341 342 return IVec4(m_baseRandomOffset.x(), m_baseRandomOffset.y(), size.x(), size.y()); 343 } 344 345 class ImageInfo 346 { 347 public: 348 ImageInfo (deUint32 format, deUint32 target, const IVec3& size); 349 350 deUint32 getFormat (void) const { return m_format; } 351 deUint32 getTarget (void) const { return m_target; } 352 const IVec3& getSize (void) const { return m_size; } 353 354 private: 355 deUint32 m_format; 356 deUint32 m_target; 357 IVec3 m_size; 358 }; 359 360 ImageInfo::ImageInfo (deUint32 format, deUint32 target, const IVec3& size) 361 : m_format (format) 362 , m_target (target) 363 , m_size (size) 364 { 365 DE_ASSERT(m_target == GL_TEXTURE_2D_ARRAY || m_target == GL_TEXTURE_3D || m_size.z() == 1); 366 DE_ASSERT(isTextureTarget(m_target) || !glu::isCompressedFormat(m_target)); 367 } 368 369 370 SeedBuilder& operator<< (SeedBuilder& builder, const ImageInfo& info) 371 { 372 builder << info.getFormat() << info.getTarget() << info.getSize(); 373 return builder; 374 } 375 376 const glu::ObjectTraits& getObjectTraits (const ImageInfo& info) 377 { 378 if (isTextureTarget(info.getTarget())) 379 return glu::objectTraits(glu::OBJECTTYPE_TEXTURE); 380 else 381 return glu::objectTraits(glu::OBJECTTYPE_RENDERBUFFER); 382 } 383 384 int getLevelCount (const ImageInfo& info) 385 { 386 const deUint32 target = info.getTarget(); 387 const IVec3 size = info.getSize(); 388 389 if (target == GL_RENDERBUFFER) 390 return 1; 391 else if (target == GL_TEXTURE_2D_ARRAY) 392 { 393 const int maxSize = de::max(size.x(), size.y()); 394 395 return deLog2Ceil32(maxSize); 396 } 397 else 398 { 399 const int maxSize = de::max(size.x(), de::max(size.y(), size.z())); 400 401 return deLog2Ceil32(maxSize); 402 } 403 } 404 405 IVec3 getLevelSize (deUint32 target, const IVec3& baseSize, int level) 406 { 407 IVec3 size; 408 409 if (target != GL_TEXTURE_2D_ARRAY) 410 { 411 for (int i = 0; i < 3; i++) 412 size[i] = de::max(baseSize[i] >> level, 1); 413 } 414 else 415 { 416 for (int i = 0; i < 2; i++) 417 size[i] = de::max(baseSize[i] >> level, 1); 418 419 size[2] = baseSize[2]; 420 } 421 422 return size; 423 } 424 425 deUint32 mapFaceNdxToFace (int ndx) 426 { 427 const deUint32 cubeFaces[] = 428 { 429 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 430 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 431 432 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 433 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 434 435 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 436 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 437 }; 438 439 return de::getSizedArrayElement<6>(cubeFaces, ndx); 440 } 441 442 // Class for iterating over mip levels and faces/slices/... of a texture. 443 class TextureImageIterator 444 { 445 public: 446 TextureImageIterator (const ImageInfo info, int levelCount); 447 ~TextureImageIterator (void) {} 448 449 // Need to call next image once, newly constructed not readable, except for getSize 450 bool nextImage (void); 451 bool hasNextImage (void) const { return (m_currentLevel < (m_levelCount - 1)) || m_currentImage < (m_levelImageCount - 1); } 452 453 int getMipLevel (void) const { return m_currentLevel; } 454 int getMipLevelCount (void) const { return m_levelCount; } 455 int getCurrentImage (void) const { return m_currentImage;} 456 int getLevelImageCount (void) const { return m_levelImageCount; } 457 IVec2 getSize (void) const { return m_levelSize.toWidth<2>(); } // Assume that image sizes never grow over iteration 458 deUint32 getTarget (void) const { return m_info.getTarget(); } 459 460 private: 461 int m_levelImageCount; // Need to be defined in CTOR for the hasNextImage to work! 462 const ImageInfo m_info; 463 int m_currentLevel; 464 IVec3 m_levelSize; 465 int m_currentImage; 466 const int m_levelCount; 467 }; 468 469 TextureImageIterator::TextureImageIterator (const ImageInfo info, int levelCount) 470 : m_levelImageCount (info.getTarget() == GL_TEXTURE_CUBE_MAP ? 6 : getLevelSize(info.getTarget(), info.getSize(), 0).z()) 471 , m_info (info) 472 , m_currentLevel (0) 473 , m_levelSize (getLevelSize(info.getTarget(), info.getSize(), 0)) 474 , m_currentImage (-1) 475 , m_levelCount (levelCount) 476 { 477 DE_ASSERT(m_levelCount <= getLevelCount(info)); 478 } 479 480 bool TextureImageIterator::nextImage (void) 481 { 482 if (!hasNextImage()) 483 return false; 484 485 m_currentImage++; 486 if (m_currentImage == m_levelImageCount) 487 { 488 m_currentLevel++; 489 m_currentImage = 0; 490 491 m_levelSize = getLevelSize(m_info.getTarget(), m_info.getSize(), m_currentLevel); 492 493 if (getTarget() == GL_TEXTURE_CUBE_MAP) 494 m_levelImageCount = 6; 495 else 496 m_levelImageCount = m_levelSize.z(); 497 } 498 DE_ASSERT(m_currentLevel < m_levelCount); 499 DE_ASSERT(m_currentImage < m_levelImageCount); 500 return true; 501 } 502 503 // Get name 504 string getTextureImageName (int textureTarget, int mipLevel, int imageIndex) 505 { 506 std::ostringstream result; 507 result << "Level"; 508 result << mipLevel; 509 switch (textureTarget) 510 { 511 case GL_TEXTURE_2D: break; 512 case GL_TEXTURE_3D: result << "Slice" << imageIndex; break; 513 case GL_TEXTURE_CUBE_MAP: result << "Face" << imageIndex; break; 514 case GL_TEXTURE_2D_ARRAY: result << "Layer" << imageIndex; break; 515 default: 516 DE_FATAL("Unsupported texture target"); 517 break; 518 } 519 return result.str(); 520 } 521 522 // Get description 523 string getTextureImageDescription (int textureTarget, int mipLevel, int imageIndex) 524 { 525 std::ostringstream result; 526 result << "level "; 527 result << mipLevel; 528 529 switch (textureTarget) 530 { 531 case GL_TEXTURE_2D: break; 532 case GL_TEXTURE_3D: result << " and Slice " << imageIndex; break; 533 case GL_TEXTURE_CUBE_MAP: result << " and Face " << imageIndex; break; 534 case GL_TEXTURE_2D_ARRAY: result << " and Layer " << imageIndex; break; 535 default: 536 DE_FATAL("Unsupported texture target"); 537 break; 538 } 539 return result.str(); 540 } 541 542 // Compute texture coordinates 543 void computeQuadTexCoords(vector<float>& texCoord, const TextureImageIterator& iteration) 544 { 545 const int currentImage = iteration.getCurrentImage(); 546 switch (iteration.getTarget()) 547 { 548 case GL_TEXTURE_2D: 549 computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f)); 550 break; 551 552 case GL_TEXTURE_3D: 553 { 554 const float r = (float(currentImage) + 0.5f) / (float)iteration.getLevelImageCount(); 555 computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0, 1, 2)); 556 break; 557 } 558 559 case GL_TEXTURE_CUBE_MAP: 560 computeQuadTexCoordCube(texCoord, glu::getCubeFaceFromGL(mapFaceNdxToFace(currentImage))); 561 break; 562 563 case GL_TEXTURE_2D_ARRAY: 564 computeQuadTexCoord2DArray(texCoord, currentImage, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f)); 565 break; 566 567 default: 568 DE_FATAL("Unsupported texture target"); 569 } 570 } 571 572 // Struct for storing each reference image with necessary metadata. 573 struct CellContents 574 { 575 IVec2 origin; 576 tcu::Surface reference; 577 std::string name; 578 std::string description; 579 }; 580 581 // Return format that has more restrictions on texel data. 582 deUint32 getMoreRestrictiveFormat (deUint32 formatA, deUint32 formatB) 583 { 584 if (formatA == formatB) 585 return formatA; 586 else if (glu::isCompressedFormat(formatA) && isAstcFormat(glu::mapGLCompressedTexFormat(formatA))) 587 return formatA; 588 else if (glu::isCompressedFormat(formatB) && isAstcFormat(glu::mapGLCompressedTexFormat(formatB))) 589 return formatB; 590 else if (isFloatFormat(formatA)) 591 { 592 DE_ASSERT(!isFloatFormat(formatB)); 593 594 return formatA; 595 } 596 else if (isFloatFormat(formatB)) 597 { 598 DE_ASSERT(!isFloatFormat(formatA)); 599 600 return formatB; 601 } 602 else if (glu::isCompressedFormat(formatA)) 603 { 604 return formatA; 605 } 606 else if (glu::isCompressedFormat(formatB)) 607 { 608 return formatB; 609 } 610 else 611 return formatA; 612 } 613 614 int getTexelBlockSize (deUint32 format) 615 { 616 if (glu::isCompressedFormat(format)) 617 return tcu::getBlockSize(glu::mapGLCompressedTexFormat(format)); 618 else 619 return glu::mapGLInternalFormat(format).getPixelSize(); 620 } 621 622 IVec3 getTexelBlockPixelSize (deUint32 format) 623 { 624 if (glu::isCompressedFormat(format)) 625 return tcu::getBlockPixelSize(glu::mapGLCompressedTexFormat(format)); 626 else 627 return IVec3(1, 1, 1); 628 } 629 630 bool isColorRenderable (deUint32 format) 631 { 632 switch (format) 633 { 634 case GL_R8: 635 case GL_RG8: 636 case GL_RGB8: 637 case GL_RGB565: 638 case GL_RGB4: 639 case GL_RGB5_A1: 640 case GL_RGBA8: 641 case GL_RGB10_A2: 642 case GL_RGB10_A2UI: 643 case GL_SRGB8_ALPHA8: 644 case GL_R8I: 645 case GL_R8UI: 646 case GL_R16I: 647 case GL_R16UI: 648 case GL_R32I: 649 case GL_R32UI: 650 case GL_RG8I: 651 case GL_RG8UI: 652 case GL_RG16I: 653 case GL_RG16UI: 654 case GL_RG32I: 655 case GL_RG32UI: 656 case GL_RGBA8I: 657 case GL_RGBA8UI: 658 case GL_RGBA16I: 659 case GL_RGBA16UI: 660 case GL_RGBA32I: 661 case GL_RGBA32UI: 662 return true; 663 664 default: 665 return false; 666 } 667 } 668 669 deUint32 getTypeForInternalFormat (deUint32 format) 670 { 671 return glu::getTransferFormat(glu::mapGLInternalFormat(format)).dataType; 672 } 673 674 void genTexel (de::Random& rng, deUint32 glFormat, int texelBlockSize, const int texelCount, deUint8* buffer) 675 { 676 if (isFloatFormat(glFormat)) 677 { 678 const tcu::TextureFormat format = glu::mapGLInternalFormat(glFormat); 679 const tcu::PixelBufferAccess access (format, texelCount, 1, 1, buffer); 680 const tcu::TextureFormatInfo info = tcu::getTextureFormatInfo(format); 681 682 for (int texelNdx = 0; texelNdx < texelCount; texelNdx++) 683 { 684 const float red = rng.getFloat(info.valueMin.x(), info.valueMax.x()); 685 const float green = rng.getFloat(info.valueMin.y(), info.valueMax.y()); 686 const float blue = rng.getFloat(info.valueMin.z(), info.valueMax.z()); 687 const float alpha = rng.getFloat(info.valueMin.w(), info.valueMax.w()); 688 689 const Vec4 color (red, green, blue, alpha); 690 691 access.setPixel(color, texelNdx, 0, 0); 692 } 693 } 694 else if (glu::isCompressedFormat(glFormat)) 695 { 696 const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(glFormat); 697 698 if (tcu::isAstcFormat(compressedFormat)) 699 { 700 const int BLOCK_SIZE = 16; 701 const deUint8 blocks[][BLOCK_SIZE] = 702 { 703 // \note All of the following blocks are valid in LDR mode. 704 { 252, 253, 255, 255, 255, 255, 255, 255, 8, 71, 90, 78, 22, 17, 26, 66, }, 705 { 252, 253, 255, 255, 255, 255, 255, 255, 220, 74, 139, 235, 249, 6, 145, 125 }, 706 { 252, 253, 255, 255, 255, 255, 255, 255, 223, 251, 28, 206, 54, 251, 160, 174 }, 707 { 252, 253, 255, 255, 255, 255, 255, 255, 39, 4, 153, 219, 180, 61, 51, 37 }, 708 { 67, 2, 0, 254, 1, 0, 64, 215, 83, 211, 159, 105, 41, 140, 50, 2 }, 709 { 67, 130, 0, 170, 84, 255, 65, 215, 83, 211, 159, 105, 41, 140, 50, 2 }, 710 { 67, 2, 129, 38, 51, 229, 95, 215, 83, 211, 159, 105, 41, 140, 50, 2 }, 711 { 67, 130, 193, 56, 213, 144, 95, 215, 83, 211, 159, 105, 41, 140, 50, 2 } 712 }; 713 714 DE_ASSERT(texelBlockSize == BLOCK_SIZE); 715 716 for (int i = 0; i < texelCount; i++) 717 { 718 const int blockNdx = rng.getInt(0, DE_LENGTH_OF_ARRAY(blocks)-1); 719 720 deMemcpy(buffer + i * BLOCK_SIZE, blocks[blockNdx], BLOCK_SIZE); 721 } 722 } 723 else 724 { 725 for (int i = 0; i < texelBlockSize * texelCount; i++) 726 { 727 const deUint8 val = rng.getUint8(); 728 729 buffer[i] = val; 730 } 731 } 732 } 733 else 734 { 735 for (int i = 0; i < texelBlockSize * texelCount; i++) 736 { 737 const deUint8 val = rng.getUint8(); 738 739 buffer[i] = val; 740 } 741 } 742 } 743 744 IVec3 divRoundUp (const IVec3& a, const IVec3& b) 745 { 746 IVec3 res; 747 748 for (int i =0; i < 3; i++) 749 res[i] = a[i] / b[i] + ((a[i] % b[i]) ? 1 : 0); 750 751 return res; 752 } 753 754 deUint32 getFormatForInternalFormat (deUint32 format) 755 { 756 return glu::getTransferFormat(glu::mapGLInternalFormat(format)).format; 757 } 758 759 void genericTexImage (const glw::Functions& gl, 760 deUint32 target, 761 int faceNdx, 762 int level, 763 const IVec3& size, 764 deUint32 format, 765 size_t dataSize, 766 const void* data) 767 { 768 const deUint32 glTarget = (target == GL_TEXTURE_CUBE_MAP ? mapFaceNdxToFace(faceNdx) : target); 769 770 DE_ASSERT(target == GL_TEXTURE_CUBE_MAP || faceNdx == 0); 771 772 if (glu::isCompressedFormat(format)) 773 { 774 switch (getTargetTexDims(target)) 775 { 776 case 2: 777 DE_ASSERT(size.z() == 1); 778 gl.compressedTexImage2D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), 0, (glw::GLsizei)dataSize, data); 779 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D failed."); 780 break; 781 782 case 3: 783 gl.compressedTexImage3D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), (glw::GLsizei)size.z(), 0, (glw::GLsizei)dataSize, data); 784 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D failed."); 785 break; 786 787 default: 788 DE_ASSERT(false); 789 } 790 } 791 else 792 { 793 const deUint32 glFormat = getFormatForInternalFormat(format); 794 const deUint32 glType = getTypeForInternalFormat(format); 795 796 switch (getTargetTexDims(target)) 797 { 798 case 2: 799 DE_ASSERT(size.z() == 1); 800 gl.texImage2D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), 0, glFormat, glType, data); 801 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D failed."); 802 break; 803 804 case 3: 805 gl.texImage3D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), (glw::GLsizei)size.z(), 0, glFormat, glType, data); 806 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D failed."); 807 break; 808 809 default: 810 DE_ASSERT(false); 811 } 812 } 813 } 814 815 void genTextureImage (const glw::Functions& gl, 816 de::Random& rng, 817 deUint32 name, 818 vector<ArrayBuffer<deUint8> >& levels, 819 const ImageInfo& info, 820 deUint32 moreRestrictiveFormat) 821 { 822 const int texelBlockSize = getTexelBlockSize(info.getFormat()); 823 const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat()); 824 825 levels.resize(getLevelCount(info)); 826 827 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 828 GLU_EXPECT_NO_ERROR(gl.getError(), "Setting pixel store aligment failed."); 829 830 gl.bindTexture(info.getTarget(), name); 831 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding texture failed."); 832 833 for (int levelNdx = 0; levelNdx < getLevelCount(info); levelNdx++) 834 { 835 ArrayBuffer<deUint8>& level = levels[levelNdx]; 836 837 const int faceCount = (info.getTarget() == GL_TEXTURE_CUBE_MAP ? 6 : 1); 838 839 const IVec3 levelPixelSize = getLevelSize(info.getTarget(), info.getSize(), levelNdx); 840 const IVec3 levelTexelBlockSize = divRoundUp(levelPixelSize, texelBlockPixelSize); 841 const int levelTexelBlockCount = levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z(); 842 const int levelSize = levelTexelBlockCount * texelBlockSize; 843 844 level.setStorage(levelSize * faceCount); 845 846 for (int faceNdx = 0; faceNdx < faceCount; faceNdx++) 847 { 848 genTexel(rng, moreRestrictiveFormat, texelBlockSize, levelTexelBlockCount, level.getElementPtr(faceNdx * levelSize)); 849 850 genericTexImage(gl, info.getTarget(), faceNdx, levelNdx, levelPixelSize, info.getFormat(), levelSize, level.getElementPtr(faceNdx * levelSize)); 851 } 852 } 853 854 gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 855 gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 856 857 if (info.getTarget() == GL_TEXTURE_3D) 858 gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 859 860 gl.texParameteri(info.getTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST); 861 gl.texParameteri(info.getTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST); 862 GLU_EXPECT_NO_ERROR(gl.getError(), "Setting texture parameters failed"); 863 864 gl.bindTexture(info.getTarget(), 0); 865 GLU_EXPECT_NO_ERROR(gl.getError(), "Unbinding texture failed."); 866 } 867 868 void genRenderbufferImage (const glw::Functions& gl, 869 de::Random& rng, 870 deUint32 name, 871 vector<ArrayBuffer<deUint8> >& levels, 872 const ImageInfo& info, 873 deUint32 moreRestrictiveFormat) 874 { 875 const IVec3 size = info.getSize(); 876 const tcu::TextureFormat format = glu::mapGLInternalFormat(info.getFormat()); 877 878 DE_ASSERT(info.getTarget() == GL_RENDERBUFFER); 879 DE_ASSERT(info.getSize().z() == 1); 880 DE_ASSERT(getLevelCount(info) == 1); 881 DE_ASSERT(!glu::isCompressedFormat(info.getFormat())); 882 883 glu::Framebuffer framebuffer(gl); 884 885 levels.resize(1); 886 levels[0].setStorage(format.getPixelSize() * size.x() * size.y()); 887 tcu::PixelBufferAccess refAccess(format, size.x(), size.y(), 1, levels[0].getPtr()); 888 889 gl.bindRenderbuffer(GL_RENDERBUFFER, name); 890 gl.renderbufferStorage(GL_RENDERBUFFER, info.getFormat(), info.getSize().x(), info.getSize().y()); 891 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding and setting storage for renderbuffer failed."); 892 893 gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer); 894 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name); 895 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding framebuffer and attaching renderbuffer failed."); 896 897 { 898 vector<deUint8> texelBlock(format.getPixelSize()); 899 900 if (isFixedPointFormat(info.getFormat())) 901 { 902 // All zeroes is only bit pattern that fixed point values can be 903 // cleared to and that is valid floating point value. 904 if (isFloatFormat(moreRestrictiveFormat)) 905 deMemset(&texelBlock[0], 0x0, texelBlock.size()); 906 else 907 { 908 // Fixed point values can be only cleared to all 0 or 1. 909 const deInt32 fill = rng.getBool() ? 0xFF : 0x0; 910 deMemset(&texelBlock[0], fill, texelBlock.size()); 911 } 912 } 913 else 914 genTexel(rng, moreRestrictiveFormat, format.getPixelSize(), 1, &(texelBlock[0])); 915 916 { 917 const tcu::ConstPixelBufferAccess texelAccess (format, 1, 1, 1, &(texelBlock[0])); 918 919 if (isIntFormat(info.getFormat())) 920 { 921 const tcu::IVec4 color = texelAccess.getPixelInt(0, 0, 0); 922 923 gl.clearBufferiv(GL_COLOR, 0, (const deInt32*)&color); 924 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer."); 925 926 DE_ASSERT(!tcu::isSRGB(format)); 927 tcu::clear(refAccess, color); 928 } 929 else if (isUintFormat(info.getFormat())) 930 { 931 const tcu::IVec4 color = texelAccess.getPixelInt(0, 0, 0); 932 933 gl.clearBufferuiv(GL_COLOR, 0, (const deUint32*)&color); 934 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer."); 935 936 DE_ASSERT(!tcu::isSRGB(format)); 937 tcu::clear(refAccess, color); 938 } 939 else 940 { 941 const tcu::Vec4 rawColor = texelAccess.getPixel(0, 0, 0); 942 const tcu::Vec4 linearColor = (tcu::isSRGB(format) ? tcu::sRGBToLinear(rawColor) : rawColor); 943 944 // rawColor bit pattern has been chosen to be "safe" in the destination format. For sRGB 945 // formats, the clear color is in linear space. Since we want the resulting bit pattern 946 // to be safe after implementation linear->sRGB transform, we must apply the inverting 947 // transform to the clear color. 948 949 if (isFloatFormat(info.getFormat())) 950 { 951 gl.clearBufferfv(GL_COLOR, 0, (const float*)&linearColor); 952 } 953 else 954 { 955 // fixed-point 956 gl.clearColor(linearColor.x(), linearColor.y(), linearColor.z(), linearColor.w()); 957 gl.clear(GL_COLOR_BUFFER_BIT); 958 } 959 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer."); 960 961 tcu::clear(refAccess, rawColor); 962 } 963 } 964 } 965 966 gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 967 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 968 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbufer and framebuffer."); 969 } 970 971 void genImage (const glw::Functions& gl, 972 de::Random& rng, 973 deUint32 name, 974 vector<ArrayBuffer<deUint8> >& levels, 975 const ImageInfo& info, 976 deUint32 moreRestrictiveFormat) 977 { 978 if (isTextureTarget(info.getTarget())) 979 genTextureImage(gl, rng, name, levels, info, moreRestrictiveFormat); 980 else 981 genRenderbufferImage(gl, rng, name, levels, info, moreRestrictiveFormat); 982 } 983 984 IVec3 getTexelBlockStride (const ImageInfo& info, int level) 985 { 986 const IVec3 size = getLevelSize(info.getTarget(), info.getSize(), level); 987 const int texelBlockSize = getTexelBlockSize(info.getFormat()); 988 const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat()); 989 const IVec3 textureTexelBlockSize = divRoundUp(size, texelBlockPixelSize); 990 991 return IVec3(texelBlockSize, textureTexelBlockSize.x() * texelBlockSize, textureTexelBlockSize.x() * textureTexelBlockSize.y() * texelBlockSize); 992 } 993 994 int sumComponents (const IVec3& v) 995 { 996 int s = 0; 997 998 for (int i = 0; i < 3; i++) 999 s += v[i]; 1000 1001 return s; 1002 } 1003 1004 void copyImageData (vector<ArrayBuffer<deUint8> >& dstImageData, 1005 const ImageInfo& dstImageInfo, 1006 int dstLevel, 1007 const IVec3& dstPos, 1008 1009 const vector<ArrayBuffer<deUint8> >& srcImageData, 1010 const ImageInfo& srcImageInfo, 1011 int srcLevel, 1012 const IVec3& srcPos, 1013 1014 const IVec3& copySize) 1015 { 1016 const ArrayBuffer<deUint8>& srcLevelData = srcImageData[srcLevel]; 1017 ArrayBuffer<deUint8>& dstLevelData = dstImageData[dstLevel]; 1018 1019 const IVec3 srcTexelBlockPixelSize = getTexelBlockPixelSize(srcImageInfo.getFormat()); 1020 const int srcTexelBlockSize = getTexelBlockSize(srcImageInfo.getFormat()); 1021 const IVec3 srcTexelPos = srcPos / srcTexelBlockPixelSize; 1022 const IVec3 srcTexelBlockStride = getTexelBlockStride(srcImageInfo, srcLevel); 1023 1024 const IVec3 dstTexelBlockPixelSize = getTexelBlockPixelSize(dstImageInfo.getFormat()); 1025 const int dstTexelBlockSize = getTexelBlockSize(dstImageInfo.getFormat()); 1026 const IVec3 dstTexelPos = dstPos / dstTexelBlockPixelSize; 1027 const IVec3 dstTexelBlockStride = getTexelBlockStride(dstImageInfo, dstLevel); 1028 1029 const IVec3 copyTexelBlockCount = copySize / srcTexelBlockPixelSize; 1030 const int texelBlockSize = srcTexelBlockSize; 1031 1032 DE_ASSERT(srcTexelBlockSize == dstTexelBlockSize); 1033 DE_UNREF(dstTexelBlockSize); 1034 1035 DE_ASSERT((copySize.x() % srcTexelBlockPixelSize.x()) == 0); 1036 DE_ASSERT((copySize.y() % srcTexelBlockPixelSize.y()) == 0); 1037 DE_ASSERT((copySize.z() % srcTexelBlockPixelSize.z()) == 0); 1038 1039 DE_ASSERT((srcPos.x() % srcTexelBlockPixelSize.x()) == 0); 1040 DE_ASSERT((srcPos.y() % srcTexelBlockPixelSize.y()) == 0); 1041 DE_ASSERT((srcPos.z() % srcTexelBlockPixelSize.z()) == 0); 1042 1043 for (int z = 0; z < copyTexelBlockCount.z(); z++) 1044 for (int y = 0; y < copyTexelBlockCount.y(); y++) 1045 { 1046 const IVec3 blockPos (0, y, z); 1047 const deUint8* const srcPtr = srcLevelData.getElementPtr(sumComponents((srcTexelPos + blockPos) * srcTexelBlockStride)); 1048 deUint8* const dstPtr = dstLevelData.getElementPtr(sumComponents((dstTexelPos + blockPos) * dstTexelBlockStride)); 1049 const int copyLineSize = copyTexelBlockCount.x() * texelBlockSize; 1050 1051 deMemcpy(dstPtr, srcPtr, copyLineSize); 1052 } 1053 } 1054 1055 vector<tcu::ConstPixelBufferAccess> getLevelAccesses (const vector<ArrayBuffer<deUint8> >& data, const ImageInfo& info) 1056 { 1057 const tcu::TextureFormat format = glu::mapGLInternalFormat(info.getFormat()); 1058 const IVec3 size = info.getSize(); 1059 1060 vector<tcu::ConstPixelBufferAccess> result; 1061 1062 DE_ASSERT((int)data.size() == getLevelCount(info)); 1063 1064 for (int level = 0; level < (int)data.size(); level++) 1065 { 1066 const IVec3 levelSize = getLevelSize(info.getTarget(), size, level); 1067 1068 result.push_back(tcu::ConstPixelBufferAccess(format, levelSize.x(), levelSize.y(), levelSize.z(), data[level].getPtr())); 1069 } 1070 1071 return result; 1072 } 1073 1074 vector<tcu::ConstPixelBufferAccess> getCubeLevelAccesses (const vector<ArrayBuffer<deUint8> >& data, 1075 const ImageInfo& info, 1076 int faceNdx) 1077 { 1078 const tcu::TextureFormat format = glu::mapGLInternalFormat(info.getFormat()); 1079 const IVec3 size = info.getSize(); 1080 const int texelBlockSize = getTexelBlockSize(info.getFormat()); 1081 const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat()); 1082 vector<tcu::ConstPixelBufferAccess> result; 1083 1084 DE_ASSERT(info.getTarget() == GL_TEXTURE_CUBE_MAP); 1085 DE_ASSERT((int)data.size() == getLevelCount(info)); 1086 1087 for (int level = 0; level < (int)data.size(); level++) 1088 { 1089 const IVec3 levelPixelSize = getLevelSize(info.getTarget(), size, level); 1090 const IVec3 levelTexelBlockSize = divRoundUp(levelPixelSize, texelBlockPixelSize); 1091 const int levelTexelBlockCount = levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z(); 1092 const int levelSize = levelTexelBlockCount * texelBlockSize; 1093 1094 result.push_back(tcu::ConstPixelBufferAccess(format, levelPixelSize.x(), levelPixelSize.y(), levelPixelSize.z(), data[level].getElementPtr(levelSize * faceNdx))); 1095 } 1096 1097 return result; 1098 } 1099 1100 void copyImage (const glw::Functions& gl, 1101 1102 deUint32 dstName, 1103 vector<ArrayBuffer<deUint8> >& dstImageData, 1104 const ImageInfo& dstImageInfo, 1105 int dstLevel, 1106 const IVec3& dstPos, 1107 1108 deUint32 srcName, 1109 const vector<ArrayBuffer<deUint8> >& srcImageData, 1110 const ImageInfo& srcImageInfo, 1111 int srcLevel, 1112 const IVec3& srcPos, 1113 1114 const IVec3& copySize) 1115 { 1116 gl.copyImageSubData(srcName, srcImageInfo.getTarget(), srcLevel, srcPos.x(), srcPos.y(), srcPos.z(), 1117 dstName, dstImageInfo.getTarget(), dstLevel, dstPos.x(), dstPos.y(), dstPos.z(), 1118 copySize.x(), copySize.y(), copySize.z()); 1119 1120 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyImageSubData failed."); 1121 1122 copyImageData(dstImageData, dstImageInfo, dstLevel, dstPos, 1123 srcImageData, srcImageInfo, srcLevel, srcPos, copySize); 1124 } 1125 1126 template<class TextureView> 1127 void renderTexture (glu::RenderContext& renderContext, 1128 TextureRenderer& renderer, 1129 ReferenceParams& renderParams, 1130 tcu::ResultCollector& results, 1131 de::Random& rng, 1132 const TextureView& refTexture, 1133 const Verify verify, 1134 TextureImageIterator& imageIterator, 1135 tcu::TestLog& log) 1136 { 1137 const tcu::RenderTarget& renderTarget = renderContext.getRenderTarget(); 1138 const tcu::RGBA threshold = renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1); 1139 const glw::Functions& gl = renderContext.getFunctions(); 1140 const IVec2 renderTargetSize = IVec2(renderTarget.getWidth(), renderTarget.getHeight()); 1141 1142 while (imageIterator.hasNextImage()) 1143 { 1144 // \note: Reserve space upfront to avoid assigning tcu::Surface, which incurs buffer mem copy. Using a 1145 // conservative estimate for simplicity 1146 const int imagesOnLevel = imageIterator.getLevelImageCount(); 1147 const int imageEstimate = (imageIterator.getMipLevelCount() - imageIterator.getMipLevel()) * imagesOnLevel; 1148 RandomizedRenderGrid renderGrid (renderTargetSize, imageIterator.getSize(), imageEstimate, rng.getUint32()); 1149 vector<CellContents> cellContents (renderGrid.getCellCount()); 1150 int cellsUsed = 0; 1151 1152 // \note: Ordering of conditions is significant. If put the other way around, the code would skip one of the 1153 // images if the grid runs out of cells before the texture runs out of images. Advancing one grid cell over the 1154 // needed number has no negative impact. 1155 while (renderGrid.nextCell() && imageIterator.nextImage()) 1156 { 1157 const int level = imageIterator.getMipLevel(); 1158 const IVec2 levelSize = imageIterator.getSize(); 1159 const IVec2 origin = renderGrid.getOrigin(); 1160 vector<float> texCoord; 1161 1162 DE_ASSERT(imageIterator.getTarget() != GL_TEXTURE_CUBE_MAP || levelSize.x() >= 4 || levelSize.y() >= 4); 1163 1164 renderParams.baseLevel = level; 1165 renderParams.maxLevel = level; 1166 1167 gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_BASE_LEVEL, level); 1168 gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_MAX_LEVEL, level); 1169 1170 computeQuadTexCoords(texCoord, imageIterator); 1171 1172 // Setup base viewport. 1173 gl.viewport(origin.x(), origin.y(), levelSize.x(), levelSize.y()); 1174 1175 // Draw. 1176 renderer.renderQuad(0, &texCoord[0], renderParams); 1177 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render."); 1178 1179 if (verify == VERIFY_COMPARE_REFERENCE) 1180 { 1181 const int target = imageIterator.getTarget(); 1182 const int imageIndex = imageIterator.getCurrentImage(); 1183 1184 cellContents[cellsUsed].origin = origin; 1185 cellContents[cellsUsed].name = getTextureImageName(target, level, imageIndex); 1186 cellContents[cellsUsed].description = getTextureImageDescription(target, level, imageIndex); 1187 1188 cellContents[cellsUsed].reference.setSize(levelSize.x(), levelSize.y()); 1189 1190 // Compute reference. 1191 sampleTexture(tcu::SurfaceAccess(cellContents[cellsUsed].reference, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams); 1192 cellsUsed++; 1193 } 1194 } 1195 1196 if (cellsUsed > 0) 1197 { 1198 const IVec4 boundingBox = renderGrid.getUsedAreaBoundingBox(); 1199 tcu::Surface renderedFrame (boundingBox[2], boundingBox[3]); 1200 1201 glu::readPixels(renderContext, boundingBox.x(), boundingBox.y(), renderedFrame.getAccess()); 1202 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to read pixels."); 1203 1204 for (int idx = 0; idx < cellsUsed; idx++) 1205 { 1206 const CellContents& cell (cellContents[idx]); 1207 const IVec2 cellOrigin = cell.origin - boundingBox.toWidth<2>(); 1208 const tcu::ConstPixelBufferAccess resultAccess = getSubregion(renderedFrame.getAccess(), cellOrigin.x(), cellOrigin.y(), cell.reference.getWidth(), cell.reference.getHeight()); 1209 1210 if (!intThresholdCompare(log, cell.name.c_str(), cell.description.c_str(), cell.reference.getAccess(), resultAccess, threshold.toIVec().cast<deUint32>(), tcu::COMPARE_LOG_ON_ERROR)) 1211 results.fail("Image comparison of " + cell.description + " failed."); 1212 else 1213 log << TestLog::Message << "Image comparison of " << cell.description << " passed." << TestLog::EndMessage;; 1214 } 1215 } 1216 } 1217 1218 gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_BASE_LEVEL, 0); 1219 gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_MAX_LEVEL, 1000); 1220 } 1221 1222 void renderTexture2DView (tcu::TestContext& testContext, 1223 glu::RenderContext& renderContext, 1224 TextureRenderer& renderer, 1225 tcu::ResultCollector& results, 1226 de::Random& rng, 1227 deUint32 name, 1228 const ImageInfo& info, 1229 const tcu::Texture2DView& refTexture, 1230 Verify verify) 1231 { 1232 tcu::TestLog& log = testContext.getLog(); 1233 const glw::Functions& gl = renderContext.getFunctions(); 1234 const tcu::TextureFormat format = refTexture.getLevel(0).getFormat(); 1235 const tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(format); 1236 1237 ReferenceParams renderParams (TEXTURETYPE_2D); 1238 TextureImageIterator imageIterator (info, getLevelCount(info)); 1239 1240 renderParams.samplerType = getSamplerType(format); 1241 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST); 1242 renderParams.colorScale = spec.lookupScale; 1243 renderParams.colorBias = spec.lookupBias; 1244 1245 gl.activeTexture(GL_TEXTURE0); 1246 gl.bindTexture(GL_TEXTURE_2D, name); 1247 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture."); 1248 1249 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1250 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1251 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1252 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1253 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state."); 1254 1255 renderTexture<tcu::Texture2DView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log); 1256 1257 gl.bindTexture(GL_TEXTURE_2D, 0); 1258 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture."); 1259 } 1260 1261 void decompressTextureLevel (const tcu::TexDecompressionParams& params, 1262 ArrayBuffer<deUint8>& levelData, 1263 tcu::PixelBufferAccess& levelAccess, 1264 const tcu::CompressedTexFormat& compressedFormat, 1265 const tcu::TextureFormat& decompressedFormat, 1266 const IVec3& levelPixelSize, 1267 const void* data) 1268 { 1269 levelData.setStorage(levelPixelSize.x() * levelPixelSize.y() * levelPixelSize.z() * decompressedFormat.getPixelSize()); 1270 levelAccess = tcu::PixelBufferAccess(decompressedFormat, levelPixelSize.x(), levelPixelSize.y(), levelPixelSize.z(), levelData.getPtr()); 1271 1272 tcu::decompress(levelAccess, compressedFormat, (const deUint8*)data, params); 1273 } 1274 1275 void decompressTexture (vector<ArrayBuffer<deUint8> >& levelDatas, 1276 vector<tcu::PixelBufferAccess>& levelAccesses, 1277 glu::RenderContext& renderContext, 1278 const ImageInfo& info, 1279 const vector<ArrayBuffer<deUint8> >& data) 1280 { 1281 const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(info.getFormat()); 1282 const tcu::TextureFormat decompressedFormat = tcu::getUncompressedFormat(compressedFormat); 1283 const IVec3 size = info.getSize(); 1284 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)); 1285 1286 de::UniquePtr<glu::ContextInfo> ctxInfo (glu::ContextInfo::create(renderContext)); 1287 tcu::TexDecompressionParams decompressParams; 1288 1289 if (tcu::isAstcFormat(compressedFormat)) 1290 { 1291 if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_hdr") && !tcu::isAstcSRGBFormat(compressedFormat)) 1292 decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_HDR); 1293 else if (isES32 || ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_ldr")) 1294 decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR); 1295 else 1296 DE_ASSERT(false); 1297 } 1298 1299 levelDatas.resize(getLevelCount(info)); 1300 levelAccesses.resize(getLevelCount(info)); 1301 1302 for (int level = 0; level < getLevelCount(info); level++) 1303 { 1304 const IVec3 levelPixelSize = getLevelSize(info.getTarget(), size, level); 1305 de::ArrayBuffer<deUint8>& levelData = levelDatas[level]; 1306 tcu::PixelBufferAccess& levelAccess = levelAccesses[level]; 1307 1308 decompressTextureLevel(decompressParams, levelData, levelAccess, compressedFormat, decompressedFormat, levelPixelSize, data[level].getPtr()); 1309 } 1310 } 1311 1312 void renderTexture2D (tcu::TestContext& testContext, 1313 glu::RenderContext& renderContext, 1314 TextureRenderer& textureRenderer, 1315 tcu::ResultCollector& results, 1316 de::Random& rng, 1317 deUint32 name, 1318 const vector<ArrayBuffer<deUint8> >& data, 1319 const ImageInfo& info, 1320 Verify verify) 1321 { 1322 if (glu::isCompressedFormat(info.getFormat())) 1323 { 1324 vector<de::ArrayBuffer<deUint8> > levelDatas; 1325 vector<tcu::PixelBufferAccess> levelAccesses; 1326 1327 decompressTexture(levelDatas, levelAccesses, renderContext, info, data); 1328 1329 { 1330 const tcu::Texture2DView refTexture((int)levelAccesses.size(), &(levelAccesses[0])); 1331 1332 renderTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1333 } 1334 } 1335 else 1336 { 1337 const vector<tcu::ConstPixelBufferAccess> levelAccesses = getLevelAccesses(data, info); 1338 const tcu::Texture2DView refTexture ((int)levelAccesses.size(), &(levelAccesses[0])); 1339 1340 renderTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1341 } 1342 } 1343 1344 void renderTexture3DView (tcu::TestContext& testContext, 1345 glu::RenderContext& renderContext, 1346 TextureRenderer& renderer, 1347 tcu::ResultCollector& results, 1348 de::Random& rng, 1349 deUint32 name, 1350 const ImageInfo& info, 1351 const tcu::Texture3DView& refTexture, 1352 Verify verify) 1353 { 1354 tcu::TestLog& log = testContext.getLog(); 1355 const glw::Functions& gl = renderContext.getFunctions(); 1356 const tcu::TextureFormat format = refTexture.getLevel(0).getFormat(); 1357 const tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(format); 1358 1359 ReferenceParams renderParams (TEXTURETYPE_3D); 1360 TextureImageIterator imageIterator (info, getLevelCount(info)); 1361 1362 renderParams.samplerType = getSamplerType(format); 1363 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST); 1364 renderParams.colorScale = spec.lookupScale; 1365 renderParams.colorBias = spec.lookupBias; 1366 1367 gl.activeTexture(GL_TEXTURE0); 1368 gl.bindTexture(GL_TEXTURE_3D, name); 1369 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture."); 1370 1371 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1372 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1373 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 1374 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1375 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1376 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state."); 1377 1378 renderTexture<tcu::Texture3DView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log); 1379 1380 gl.bindTexture(GL_TEXTURE_3D, 0); 1381 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture."); 1382 } 1383 1384 void renderTexture3D (tcu::TestContext& testContext, 1385 glu::RenderContext& renderContext, 1386 TextureRenderer& textureRenderer, 1387 tcu::ResultCollector& results, 1388 de::Random& rng, 1389 deUint32 name, 1390 const vector<ArrayBuffer<deUint8> >& data, 1391 const ImageInfo& info, 1392 Verify verify) 1393 { 1394 if (glu::isCompressedFormat(info.getFormat())) 1395 { 1396 vector<de::ArrayBuffer<deUint8> > levelDatas; 1397 vector<tcu::PixelBufferAccess> levelAccesses; 1398 1399 decompressTexture(levelDatas, levelAccesses, renderContext, info, data); 1400 1401 { 1402 const tcu::Texture3DView refTexture((int)levelAccesses.size(), &(levelAccesses[0])); 1403 1404 renderTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1405 } 1406 } 1407 else 1408 { 1409 const vector<tcu::ConstPixelBufferAccess> levelAccesses = getLevelAccesses(data, info); 1410 const tcu::Texture3DView refTexture ((int)levelAccesses.size(), &(levelAccesses[0])); 1411 1412 renderTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1413 } 1414 } 1415 1416 void renderTextureCubemapView (tcu::TestContext& testContext, 1417 glu::RenderContext& renderContext, 1418 TextureRenderer& renderer, 1419 tcu::ResultCollector& results, 1420 de::Random& rng, 1421 deUint32 name, 1422 const ImageInfo& info, 1423 const tcu::TextureCubeView& refTexture, 1424 Verify verify) 1425 { 1426 tcu::TestLog& log = testContext.getLog(); 1427 const glw::Functions& gl = renderContext.getFunctions(); 1428 const tcu::TextureFormat format = refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X).getFormat(); 1429 const tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(format); 1430 1431 ReferenceParams renderParams (TEXTURETYPE_CUBE); 1432 // \note It seems we can't reliably sample two smallest texture levels with cubemaps 1433 TextureImageIterator imageIterator (info, getLevelCount(info) - 2); 1434 1435 renderParams.samplerType = getSamplerType(format); 1436 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST); 1437 renderParams.colorScale = spec.lookupScale; 1438 renderParams.colorBias = spec.lookupBias; 1439 1440 gl.activeTexture(GL_TEXTURE0); 1441 gl.bindTexture(GL_TEXTURE_CUBE_MAP, name); 1442 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture."); 1443 1444 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1445 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1446 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1447 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1448 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state."); 1449 1450 renderTexture<tcu::TextureCubeView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log); 1451 1452 gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0); 1453 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture."); 1454 } 1455 1456 void renderTextureCubemap (tcu::TestContext& testContext, 1457 glu::RenderContext& renderContext, 1458 TextureRenderer& textureRenderer, 1459 tcu::ResultCollector& results, 1460 de::Random& rng, 1461 deUint32 name, 1462 const vector<ArrayBuffer<deUint8> >& data, 1463 const ImageInfo& info, 1464 Verify verify) 1465 { 1466 if (glu::isCompressedFormat(info.getFormat())) 1467 { 1468 const tcu::CompressedTexFormat& compressedFormat = glu::mapGLCompressedTexFormat(info.getFormat()); 1469 const tcu::TextureFormat& decompressedFormat = tcu::getUncompressedFormat(compressedFormat); 1470 1471 const int texelBlockSize = getTexelBlockSize(info.getFormat()); 1472 const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat()); 1473 1474 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2)); 1475 1476 vector<tcu::PixelBufferAccess> levelAccesses[6]; 1477 vector<ArrayBuffer<deUint8> > levelDatas[6]; 1478 de::UniquePtr<glu::ContextInfo> ctxInfo (glu::ContextInfo::create(renderContext)); 1479 tcu::TexDecompressionParams decompressParams; 1480 1481 if (tcu::isAstcFormat(compressedFormat)) 1482 { 1483 if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_hdr") && !tcu::isAstcSRGBFormat(compressedFormat)) 1484 decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_HDR); 1485 else if (isES32 || ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_ldr")) 1486 decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR); 1487 else 1488 DE_ASSERT(false); 1489 } 1490 1491 for (int faceNdx = 0; faceNdx < 6; faceNdx++) 1492 { 1493 levelAccesses[faceNdx].resize(getLevelCount(info)); 1494 levelDatas[faceNdx].resize(getLevelCount(info)); 1495 } 1496 1497 for (int level = 0; level < getLevelCount(info); level++) 1498 { 1499 for (int faceNdx = 0; faceNdx < 6; faceNdx++) 1500 { 1501 const IVec3 levelPixelSize = getLevelSize(info.getTarget(), info.getSize(), level); 1502 const IVec3 levelTexelBlockSize = divRoundUp(levelPixelSize, texelBlockPixelSize); 1503 const int levelTexelBlockCount = levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z(); 1504 const int levelSize = levelTexelBlockCount * texelBlockSize; 1505 1506 const deUint8* dataPtr = data[level].getElementPtr(faceNdx * levelSize); 1507 tcu::PixelBufferAccess& levelAccess = levelAccesses[faceNdx][level]; 1508 ArrayBuffer<deUint8>& levelData = levelDatas[faceNdx][level]; 1509 1510 decompressTextureLevel(decompressParams, levelData, levelAccess, compressedFormat, decompressedFormat, levelPixelSize, dataPtr); 1511 } 1512 } 1513 1514 const tcu::ConstPixelBufferAccess* levels[6]; 1515 1516 for (int faceNdx = 0; faceNdx < 6; faceNdx++) 1517 levels[glu::getCubeFaceFromGL(mapFaceNdxToFace(faceNdx))] = &(levelAccesses[faceNdx][0]); 1518 1519 { 1520 const tcu::TextureCubeView refTexture(getLevelCount(info), levels); 1521 1522 renderTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1523 } 1524 } 1525 else 1526 { 1527 const vector<tcu::ConstPixelBufferAccess> levelAccesses[6] = 1528 { 1529 getCubeLevelAccesses(data, info, 0), 1530 getCubeLevelAccesses(data, info, 1), 1531 getCubeLevelAccesses(data, info, 2), 1532 getCubeLevelAccesses(data, info, 3), 1533 getCubeLevelAccesses(data, info, 4), 1534 getCubeLevelAccesses(data, info, 5), 1535 }; 1536 1537 const tcu::ConstPixelBufferAccess* levels[6]; 1538 1539 for (int faceNdx = 0; faceNdx < 6; faceNdx++) 1540 levels[glu::getCubeFaceFromGL(mapFaceNdxToFace(faceNdx))] = &(levelAccesses[faceNdx][0]); 1541 1542 { 1543 const tcu::TextureCubeView refTexture(getLevelCount(info), levels); 1544 1545 renderTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1546 } 1547 } 1548 } 1549 1550 void renderTexture2DArrayView (tcu::TestContext& testContext, 1551 glu::RenderContext& renderContext, 1552 TextureRenderer& renderer, 1553 tcu::ResultCollector& results, 1554 de::Random& rng, 1555 deUint32 name, 1556 const ImageInfo& info, 1557 const tcu::Texture2DArrayView& refTexture, 1558 Verify verify) 1559 { 1560 tcu::TestLog& log = testContext.getLog(); 1561 const glw::Functions& gl = renderContext.getFunctions(); 1562 const tcu::TextureFormat format = refTexture.getLevel(0).getFormat(); 1563 const tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(format); 1564 1565 ReferenceParams renderParams (TEXTURETYPE_2D_ARRAY); 1566 TextureImageIterator imageIterator (info, getLevelCount(info)); 1567 1568 renderParams.samplerType = getSamplerType(format); 1569 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST); 1570 renderParams.colorScale = spec.lookupScale; 1571 renderParams.colorBias = spec.lookupBias; 1572 1573 gl.activeTexture(GL_TEXTURE0); 1574 gl.bindTexture(GL_TEXTURE_2D_ARRAY, name); 1575 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture."); 1576 1577 gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1578 gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1579 gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1580 gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1581 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state."); 1582 1583 renderTexture<tcu::Texture2DArrayView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log); 1584 1585 gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0); 1586 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture."); 1587 } 1588 1589 void renderTexture2DArray (tcu::TestContext& testContext, 1590 glu::RenderContext& renderContext, 1591 TextureRenderer& textureRenderer, 1592 tcu::ResultCollector& results, 1593 de::Random& rng, 1594 deUint32 name, 1595 const vector<ArrayBuffer<deUint8> >& data, 1596 const ImageInfo& info, 1597 Verify verify) 1598 { 1599 if (glu::isCompressedFormat(info.getFormat())) 1600 { 1601 vector<de::ArrayBuffer<deUint8> > levelDatas; 1602 vector<tcu::PixelBufferAccess> levelAccesses; 1603 1604 decompressTexture(levelDatas, levelAccesses, renderContext, info, data); 1605 1606 { 1607 const tcu::Texture2DArrayView refTexture((int)levelAccesses.size(), &(levelAccesses[0])); 1608 1609 renderTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1610 } 1611 } 1612 else 1613 { 1614 const vector<tcu::ConstPixelBufferAccess> levelAccesses = getLevelAccesses(data, info); 1615 const tcu::Texture2DArrayView refTexture ((int)levelAccesses.size(), &(levelAccesses[0])); 1616 1617 renderTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify); 1618 } 1619 } 1620 1621 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format) 1622 { 1623 switch (tcu::getTextureChannelClass(format.type)) 1624 { 1625 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 1626 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 1627 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 1628 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1629 1630 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 1631 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32); 1632 1633 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 1634 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32); 1635 1636 default: 1637 DE_ASSERT(false); 1638 return tcu::TextureFormat(); 1639 } 1640 } 1641 1642 Vec4 calculateThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat) 1643 { 1644 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT); 1645 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT); 1646 1647 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER); 1648 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER); 1649 1650 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER); 1651 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER); 1652 1653 { 1654 const tcu::IVec4 srcBits = tcu::getTextureFormatBitDepth(sourceFormat); 1655 const tcu::IVec4 readBits = tcu::getTextureFormatBitDepth(readPixelsFormat); 1656 1657 return Vec4(1.0f) / ((tcu::IVec4(1) << (tcu::min(srcBits, readBits))) - tcu::IVec4(1)).cast<float>(); 1658 } 1659 } 1660 1661 void renderRenderbuffer (tcu::TestContext& testContext, 1662 glu::RenderContext& renderContext, 1663 tcu::ResultCollector& results, 1664 deUint32 name, 1665 const vector<ArrayBuffer<deUint8> >& data, 1666 const ImageInfo& info, 1667 Verify verify) 1668 { 1669 const glw::Functions& gl = renderContext.getFunctions(); 1670 TestLog& log = testContext.getLog(); 1671 1672 const tcu::TextureFormat format = glu::mapGLInternalFormat(info.getFormat()); 1673 const IVec3 size = info.getSize(); 1674 const tcu::ConstPixelBufferAccess refRenderbuffer (format, size.x(), size.y(), 1, data[0].getPtr()); 1675 const tcu::TextureFormat readPixelsFormat = getReadPixelFormat(format); 1676 tcu::TextureLevel renderbuffer (readPixelsFormat, size.x(), size.y()); 1677 1678 DE_ASSERT(size.z() == 1); 1679 DE_ASSERT(data.size() == 1); 1680 1681 { 1682 glu::Framebuffer framebuffer(gl); 1683 1684 gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer); 1685 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create and bind framebuffer."); 1686 1687 gl.bindRenderbuffer(GL_RENDERBUFFER, name); 1688 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name); 1689 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind and attach renderbuffer to framebuffer."); 1690 1691 if (verify) 1692 glu::readPixels(renderContext, 0, 0, renderbuffer.getAccess()); 1693 1694 gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 1695 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1696 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbuffer and framebuffer."); 1697 } 1698 1699 if (verify == VERIFY_COMPARE_REFERENCE) 1700 { 1701 if (isFloatFormat(info.getFormat())) 1702 { 1703 const tcu::UVec4 threshold (2, 2, 2, 2); 1704 1705 if (!(tcu::floatUlpThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR))) 1706 results.fail("Image comparison failed."); 1707 else 1708 log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage; 1709 } 1710 else if (isIntFormat(info.getFormat()) || isUintFormat(info.getFormat())) 1711 { 1712 const tcu::UVec4 threshold (1, 1, 1, 1); 1713 1714 if (!(tcu::intThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR))) 1715 results.fail("Image comparison failed."); 1716 else 1717 log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage; 1718 } 1719 else 1720 { 1721 const Vec4 threshold = calculateThreshold(format, readPixelsFormat); 1722 1723 if (!(tcu::floatThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR))) 1724 results.fail("Image comparison failed."); 1725 else 1726 log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage; 1727 } 1728 } 1729 } 1730 1731 void render (tcu::TestContext& testContext, 1732 glu::RenderContext& renderContext, 1733 TextureRenderer& textureRenderer, 1734 tcu::ResultCollector& results, 1735 de::Random& rng, 1736 deUint32 name, 1737 const vector<ArrayBuffer<deUint8> >& data, 1738 const ImageInfo& info, 1739 Verify verify) 1740 { 1741 switch (info.getTarget()) 1742 { 1743 case GL_TEXTURE_2D: 1744 renderTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1745 break; 1746 1747 case GL_TEXTURE_3D: 1748 renderTexture3D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1749 break; 1750 1751 case GL_TEXTURE_CUBE_MAP: 1752 renderTextureCubemap(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1753 break; 1754 1755 case GL_TEXTURE_2D_ARRAY: 1756 renderTexture2DArray(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1757 break; 1758 1759 case GL_RENDERBUFFER: 1760 renderRenderbuffer(testContext, renderContext, results, name, data, info, verify); 1761 break; 1762 1763 default: 1764 DE_ASSERT(false); 1765 } 1766 } 1767 1768 void logTestImageInfo (TestLog& log, 1769 const ImageInfo& imageInfo) 1770 { 1771 log << TestLog::Message << "Target: " << targetToName(imageInfo.getTarget()) << TestLog::EndMessage; 1772 log << TestLog::Message << "Size: " << imageInfo.getSize() << TestLog::EndMessage; 1773 log << TestLog::Message << "Levels: " << getLevelCount(imageInfo) << TestLog::EndMessage; 1774 log << TestLog::Message << "Format: " << formatToName(imageInfo.getFormat()) << TestLog::EndMessage; 1775 } 1776 1777 void logTestInfo (TestLog& log, 1778 const ImageInfo& srcImageInfo, 1779 const ImageInfo& dstImageInfo) 1780 { 1781 tcu::ScopedLogSection section(log, "TestCaseInfo", "Test case info"); 1782 1783 log << TestLog::Message << "Testing copying from " << targetToName(srcImageInfo.getTarget()) << " to " << targetToName(dstImageInfo.getTarget()) << "." << TestLog::EndMessage; 1784 1785 { 1786 tcu::ScopedLogSection srcSection(log, "Source image info.", "Source image info."); 1787 logTestImageInfo(log, srcImageInfo); 1788 } 1789 1790 { 1791 tcu::ScopedLogSection dstSection(log, "Destination image info.", "Destination image info."); 1792 logTestImageInfo(log, dstImageInfo); 1793 } 1794 } 1795 1796 class CopyImageTest : public TestCase 1797 { 1798 public: 1799 CopyImageTest (Context& context, 1800 const ImageInfo& srcImage, 1801 const ImageInfo& dstImage, 1802 const char* name, 1803 const char* description); 1804 1805 ~CopyImageTest (void); 1806 1807 void init (void); 1808 void deinit (void); 1809 1810 TestCase::IterateResult iterate (void); 1811 1812 private: 1813 1814 void logTestInfoIter (void); 1815 void createImagesIter (void); 1816 void destroyImagesIter (void); 1817 void verifySourceIter (void); 1818 void verifyDestinationIter (void); 1819 void renderSourceIter (void); 1820 void renderDestinationIter (void); 1821 void copyImageIter (void); 1822 1823 typedef void (CopyImageTest::*IterationFunc)(void); 1824 1825 struct Iteration 1826 { 1827 Iteration (int methodCount_, const IterationFunc* methods_) 1828 : methodCount (methodCount_) 1829 , methods (methods_) 1830 { 1831 } 1832 1833 int methodCount; 1834 const IterationFunc* methods; 1835 }; 1836 1837 struct State 1838 { 1839 State (int seed, 1840 tcu::TestLog& log, 1841 glu::RenderContext& renderContext) 1842 : rng (seed) 1843 , results (log) 1844 , srcImage (NULL) 1845 , dstImage (NULL) 1846 , textureRenderer (renderContext, log, glu::getContextTypeGLSLVersion(renderContext.getType()), glu::PRECISION_HIGHP) 1847 { 1848 } 1849 1850 ~State (void) 1851 { 1852 delete srcImage; 1853 delete dstImage; 1854 } 1855 1856 de::Random rng; 1857 tcu::ResultCollector results; 1858 glu::ObjectWrapper* srcImage; 1859 glu::ObjectWrapper* dstImage; 1860 TextureRenderer textureRenderer; 1861 1862 vector<ArrayBuffer<deUint8> > srcImageLevels; 1863 vector<ArrayBuffer<deUint8> > dstImageLevels; 1864 }; 1865 1866 const ImageInfo m_srcImageInfo; 1867 const ImageInfo m_dstImageInfo; 1868 1869 int m_iteration; 1870 State* m_state; 1871 }; 1872 1873 CopyImageTest::CopyImageTest (Context& context, 1874 const ImageInfo& srcImage, 1875 const ImageInfo& dstImage, 1876 const char* name, 1877 const char* description) 1878 : TestCase (context, name, description) 1879 , m_srcImageInfo (srcImage) 1880 , m_dstImageInfo (dstImage) 1881 1882 , m_iteration (0) 1883 , m_state (NULL) 1884 { 1885 } 1886 1887 CopyImageTest::~CopyImageTest (void) 1888 { 1889 deinit(); 1890 } 1891 1892 void checkFormatSupport (glu::ContextInfo& info, deUint32 format, deUint32 target, glu::RenderContext& ctx) 1893 { 1894 const bool isES32 = glu::contextSupports(ctx.getType(), glu::ApiType::es(3, 2)); 1895 1896 if (glu::isCompressedFormat(format)) 1897 { 1898 if (isAstcFormat(glu::mapGLCompressedTexFormat(format))) 1899 { 1900 DE_ASSERT(target != GL_RENDERBUFFER); 1901 if (!info.isExtensionSupported("GL_KHR_texture_compression_astc_hdr") && 1902 !info.isExtensionSupported("GL_OES_texture_compression_astc")) 1903 { 1904 if (target == GL_TEXTURE_3D) 1905 TCU_THROW(NotSupportedError, "TEXTURE_3D target requires HDR astc support."); 1906 if (!isES32 && !info.isExtensionSupported("GL_KHR_texture_compression_astc_ldr")) 1907 TCU_THROW(NotSupportedError, "Compressed astc texture not supported."); 1908 } 1909 } 1910 else 1911 { 1912 if (!info.isCompressedTextureFormatSupported(format)) 1913 TCU_THROW(NotSupportedError, "Compressed texture not supported."); 1914 } 1915 } 1916 } 1917 1918 void CopyImageTest::init (void) 1919 { 1920 de::UniquePtr<glu::ContextInfo> ctxInfo(glu::ContextInfo::create(m_context.getRenderContext())); 1921 const bool isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)); 1922 1923 if (!isES32 && !ctxInfo->isExtensionSupported("GL_EXT_copy_image")) 1924 throw tcu::NotSupportedError("Extension GL_EXT_copy_image not supported.", "", __FILE__, __LINE__); 1925 1926 checkFormatSupport(*ctxInfo, m_srcImageInfo.getFormat(), m_srcImageInfo.getTarget(), m_context.getRenderContext()); 1927 checkFormatSupport(*ctxInfo, m_dstImageInfo.getFormat(), m_dstImageInfo.getTarget(), m_context.getRenderContext()); 1928 1929 { 1930 SeedBuilder builder; 1931 1932 builder << 903980 1933 << m_srcImageInfo 1934 << m_dstImageInfo; 1935 1936 m_state = new State(builder.get(), m_testCtx.getLog(), m_context.getRenderContext()); 1937 } 1938 } 1939 1940 void CopyImageTest::deinit (void) 1941 { 1942 delete m_state; 1943 m_state = NULL; 1944 } 1945 1946 void CopyImageTest::logTestInfoIter (void) 1947 { 1948 TestLog& log = m_testCtx.getLog(); 1949 1950 logTestInfo(log, m_srcImageInfo, m_dstImageInfo); 1951 } 1952 1953 void CopyImageTest::createImagesIter (void) 1954 { 1955 TestLog& log = m_testCtx.getLog(); 1956 glu::RenderContext& renderContext = m_context.getRenderContext(); 1957 const glw::Functions& gl = renderContext.getFunctions(); 1958 const deUint32 moreRestrictiveFormat = getMoreRestrictiveFormat(m_srcImageInfo.getFormat(), m_dstImageInfo.getFormat()); 1959 de::Random& rng = m_state->rng; 1960 1961 DE_ASSERT(!m_state->srcImage); 1962 DE_ASSERT(!m_state->dstImage); 1963 1964 m_state->srcImage = new glu::ObjectWrapper(gl, getObjectTraits(m_srcImageInfo)); 1965 m_state->dstImage = new glu::ObjectWrapper(gl, getObjectTraits(m_dstImageInfo)); 1966 1967 { 1968 glu::ObjectWrapper& srcImage = *m_state->srcImage; 1969 glu::ObjectWrapper& dstImage = *m_state->dstImage; 1970 1971 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 1972 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 1973 1974 log << TestLog::Message << "Creating source image." << TestLog::EndMessage; 1975 genImage(gl, rng, *srcImage, srcImageLevels, m_srcImageInfo, moreRestrictiveFormat); 1976 1977 log << TestLog::Message << "Creating destination image." << TestLog::EndMessage; 1978 genImage(gl, rng, *dstImage, dstImageLevels, m_dstImageInfo, moreRestrictiveFormat); 1979 } 1980 } 1981 1982 void CopyImageTest::destroyImagesIter (void) 1983 { 1984 TestLog& log = m_testCtx.getLog(); 1985 1986 log << TestLog::Message << "Deleting source image. " << TestLog::EndMessage; 1987 1988 delete m_state->srcImage; 1989 m_state->srcImage = NULL; 1990 m_state->srcImageLevels.clear(); 1991 1992 log << TestLog::Message << "Deleting destination image. " << TestLog::EndMessage; 1993 1994 delete m_state->dstImage; 1995 m_state->dstImage = NULL; 1996 m_state->dstImageLevels.clear(); 1997 } 1998 1999 void CopyImageTest::verifySourceIter (void) 2000 { 2001 TestLog& log = m_testCtx.getLog(); 2002 const tcu::ScopedLogSection sourceSection (log, "Source image verify.", "Source image verify."); 2003 2004 de::Random& rng = m_state->rng; 2005 tcu::ResultCollector& results = m_state->results; 2006 glu::ObjectWrapper& srcImage = *m_state->srcImage; 2007 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 2008 2009 log << TestLog::Message << "Verifying source image." << TestLog::EndMessage; 2010 2011 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_COMPARE_REFERENCE); 2012 } 2013 2014 void CopyImageTest::verifyDestinationIter (void) 2015 { 2016 TestLog& log = m_testCtx.getLog(); 2017 const tcu::ScopedLogSection destinationSection (log, "Destination image verify.", "Destination image verify."); 2018 2019 de::Random& rng = m_state->rng; 2020 tcu::ResultCollector& results = m_state->results; 2021 glu::ObjectWrapper& dstImage = *m_state->dstImage; 2022 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 2023 2024 log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage; 2025 2026 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_COMPARE_REFERENCE); 2027 } 2028 2029 void CopyImageTest::renderSourceIter (void) 2030 { 2031 TestLog& log = m_testCtx.getLog(); 2032 const tcu::ScopedLogSection sourceSection (log, "Source image verify.", "Source image verify."); 2033 2034 de::Random& rng = m_state->rng; 2035 tcu::ResultCollector& results = m_state->results; 2036 glu::ObjectWrapper& srcImage = *m_state->srcImage; 2037 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 2038 2039 log << TestLog::Message << "Verifying source image." << TestLog::EndMessage; 2040 2041 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_NONE); 2042 } 2043 2044 void CopyImageTest::renderDestinationIter (void) 2045 { 2046 TestLog& log = m_testCtx.getLog(); 2047 const tcu::ScopedLogSection destinationSection (log, "Destination image verify.", "Destination image verify."); 2048 2049 de::Random& rng = m_state->rng; 2050 tcu::ResultCollector& results = m_state->results; 2051 glu::ObjectWrapper& dstImage = *m_state->dstImage; 2052 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 2053 2054 log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage; 2055 2056 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_NONE); 2057 } 2058 2059 struct Copy 2060 { 2061 Copy (const IVec3& srcPos_, 2062 int srcLevel_, 2063 2064 const IVec3& dstPos_, 2065 int dstLevel_, 2066 2067 const IVec3& size_, 2068 const IVec3& dstSize_) 2069 : srcPos (srcPos_) 2070 , srcLevel (srcLevel_) 2071 2072 , dstPos (dstPos_) 2073 , dstLevel (dstLevel_) 2074 2075 , size (size_) 2076 , dstSize (dstSize_) 2077 { 2078 } 2079 2080 IVec3 srcPos; 2081 int srcLevel; 2082 IVec3 dstPos; 2083 int dstLevel; 2084 IVec3 size; 2085 IVec3 dstSize; //!< used only for logging 2086 }; 2087 2088 int getLastFullLevel (const ImageInfo& info) 2089 { 2090 const int levelCount = getLevelCount(info); 2091 const IVec3 blockPixelSize = getTexelBlockPixelSize(info.getFormat()); 2092 2093 for (int level = 0; level < levelCount; level++) 2094 { 2095 const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level); 2096 2097 if (levelSize.x() < blockPixelSize.x() || levelSize.y() < blockPixelSize.y() || levelSize.z() < blockPixelSize.z()) 2098 return level - 1; 2099 } 2100 2101 return levelCount -1; 2102 } 2103 2104 void generateCopies (vector<Copy>& copies, const ImageInfo& srcInfo, const ImageInfo& dstInfo) 2105 { 2106 const deUint32 srcTarget = srcInfo.getTarget(); 2107 const deUint32 dstTarget = dstInfo.getTarget(); 2108 2109 const bool srcIsTexture = isTextureTarget(srcInfo.getTarget()); 2110 const bool dstIsTexture = isTextureTarget(dstInfo.getTarget()); 2111 2112 const bool srcIsCube = srcTarget == GL_TEXTURE_CUBE_MAP; 2113 const bool dstIsCube = dstTarget == GL_TEXTURE_CUBE_MAP; 2114 2115 const IVec3 srcBlockPixelSize = getTexelBlockPixelSize(srcInfo.getFormat()); 2116 const IVec3 dstBlockPixelSize = getTexelBlockPixelSize(dstInfo.getFormat()); 2117 2118 const int levels[] = 2119 { 2120 0, 1, -1 2121 }; 2122 2123 for (int levelNdx = 0; levelNdx < (srcIsTexture || dstIsTexture ? DE_LENGTH_OF_ARRAY(levels) : 1); levelNdx++) 2124 { 2125 const int srcLevel = (srcIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(srcInfo)) : 0); 2126 const int dstLevel = (dstIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(dstInfo)) : 0); 2127 2128 const IVec3 srcSize = getLevelSize(srcInfo.getTarget(), srcInfo.getSize(), srcLevel); 2129 const IVec3 dstSize = getLevelSize(dstInfo.getTarget(), dstInfo.getSize(), dstLevel); 2130 2131 // \note These are rounded down 2132 const IVec3 srcCompleteBlockSize = IVec3(srcSize.x() / srcBlockPixelSize.x(), srcSize.y() / srcBlockPixelSize.y(), (srcIsCube ? 6 : srcSize.z() / srcBlockPixelSize.z())); 2133 const IVec3 dstCompleteBlockSize = IVec3(dstSize.x() / dstBlockPixelSize.x(), dstSize.y() / dstBlockPixelSize.y(), (dstIsCube ? 6 : dstSize.z() / dstBlockPixelSize.z())); 2134 2135 const IVec3 maxCopyBlockSize = tcu::min(srcCompleteBlockSize, dstCompleteBlockSize); 2136 2137 // \note These are rounded down 2138 const int copyBlockWidth = de::max((2 * (maxCopyBlockSize.x() / 4)) - 1, 1); 2139 const int copyBlockHeight = de::max((2 * (maxCopyBlockSize.y() / 4)) - 1, 1); 2140 const int copyBlockDepth = de::max((2 * (maxCopyBlockSize.z() / 4)) - 1, 1); 2141 2142 // Copy NPOT block to (0,0,0) from other corner on src 2143 { 2144 const IVec3 copyBlockSize (copyBlockWidth, copyBlockHeight, copyBlockDepth); 2145 const IVec3 srcBlockPos (srcCompleteBlockSize - copyBlockSize); 2146 const IVec3 dstBlockPos (0, 0, 0); 2147 2148 const IVec3 srcPos (srcBlockPos * srcBlockPixelSize); 2149 const IVec3 dstPos (dstBlockPos * dstBlockPixelSize); 2150 const IVec3 srcCopySize (copyBlockSize * srcBlockPixelSize); 2151 const IVec3 dstCopySize (copyBlockSize * dstBlockPixelSize); 2152 2153 copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize)); 2154 } 2155 2156 // Copy NPOT block from (0,0,0) to other corner on dst 2157 { 2158 const IVec3 copyBlockSize (copyBlockWidth, copyBlockHeight, copyBlockDepth); 2159 const IVec3 srcBlockPos (0, 0, 0); 2160 const IVec3 dstBlockPos (dstCompleteBlockSize - copyBlockSize); 2161 2162 const IVec3 srcPos (srcBlockPos * srcBlockPixelSize); 2163 const IVec3 dstPos (dstBlockPos * dstBlockPixelSize); 2164 const IVec3 srcCopySize (copyBlockSize * srcBlockPixelSize); 2165 const IVec3 dstCopySize (copyBlockSize * dstBlockPixelSize); 2166 2167 copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize)); 2168 } 2169 2170 // Copy NPOT block near the corner with high coordinates 2171 { 2172 const IVec3 copyBlockSize (copyBlockWidth, copyBlockHeight, copyBlockDepth); 2173 const IVec3 srcBlockPos (tcu::max((srcCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0))); 2174 const IVec3 dstBlockPos (tcu::max((dstCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0))); 2175 2176 const IVec3 srcPos (srcBlockPos * srcBlockPixelSize); 2177 const IVec3 dstPos (dstBlockPos * dstBlockPixelSize); 2178 const IVec3 srcCopySize (copyBlockSize * srcBlockPixelSize); 2179 const IVec3 dstCopySize (copyBlockSize * dstBlockPixelSize); 2180 2181 copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize)); 2182 } 2183 } 2184 } 2185 2186 void CopyImageTest::copyImageIter (void) 2187 { 2188 TestLog& log = m_testCtx.getLog(); 2189 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2190 glu::ObjectWrapper& srcImage = *m_state->srcImage; 2191 glu::ObjectWrapper& dstImage = *m_state->dstImage; 2192 2193 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 2194 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 2195 vector<Copy> copies; 2196 2197 generateCopies(copies, m_srcImageInfo, m_dstImageInfo); 2198 2199 for (int copyNdx = 0; copyNdx < (int)copies.size(); copyNdx++) 2200 { 2201 const Copy& copy = copies[copyNdx]; 2202 2203 log << TestLog::Message 2204 << "Copying area with size " << copy.size 2205 << " from source image position " << copy.srcPos << " and mipmap level " << copy.srcLevel 2206 << " to destination image position " << copy.dstPos << " and mipmap level " << copy.dstLevel << ". " 2207 << "Size in destination format is " << copy.dstSize 2208 << TestLog::EndMessage; 2209 2210 copyImage(gl, *dstImage, dstImageLevels, m_dstImageInfo, copy.dstLevel, copy.dstPos, 2211 *srcImage, srcImageLevels, m_srcImageInfo, copy.srcLevel, copy.srcPos, copy.size); 2212 } 2213 } 2214 2215 TestCase::IterateResult CopyImageTest::iterate (void) 2216 { 2217 // Note: Returning from iterate() has two side-effects: it touches 2218 // watchdog and calls eglSwapBuffers. For the first it's important 2219 // to keep work per iteration reasonable to avoid 2220 // timeouts. Because of the latter, it's prudent to do more than 2221 // trivial amount of work. Otherwise we'll end up waiting for a 2222 // new buffer in swap, it seems. 2223 2224 // The split below tries to combine trivial work with actually 2225 // expensive rendering iterations without having too much 2226 // rendering in one iteration to avoid timeouts. 2227 const IterationFunc iteration1[] = 2228 { 2229 &CopyImageTest::logTestInfoIter, 2230 &CopyImageTest::createImagesIter, 2231 &CopyImageTest::renderSourceIter 2232 }; 2233 const IterationFunc iteration2[] = 2234 { 2235 &CopyImageTest::renderDestinationIter 2236 }; 2237 const IterationFunc iteration3[] = 2238 { 2239 &CopyImageTest::copyImageIter, 2240 &CopyImageTest::verifySourceIter 2241 }; 2242 const IterationFunc iteration4[] = 2243 { 2244 &CopyImageTest::verifyDestinationIter, 2245 &CopyImageTest::destroyImagesIter 2246 }; 2247 const IterationFunc iteration5[] = 2248 { 2249 &CopyImageTest::createImagesIter, 2250 &CopyImageTest::copyImageIter, 2251 &CopyImageTest::verifySourceIter 2252 }; 2253 const IterationFunc iteration6[] = 2254 { 2255 &CopyImageTest::verifyDestinationIter, 2256 &CopyImageTest::destroyImagesIter 2257 }; 2258 const Iteration iterations[] = 2259 { 2260 Iteration(DE_LENGTH_OF_ARRAY(iteration1), iteration1), 2261 Iteration(DE_LENGTH_OF_ARRAY(iteration2), iteration2), 2262 Iteration(DE_LENGTH_OF_ARRAY(iteration3), iteration3), 2263 Iteration(DE_LENGTH_OF_ARRAY(iteration4), iteration4), 2264 Iteration(DE_LENGTH_OF_ARRAY(iteration5), iteration5), 2265 Iteration(DE_LENGTH_OF_ARRAY(iteration6), iteration6) 2266 }; 2267 2268 DE_ASSERT(m_iteration < DE_LENGTH_OF_ARRAY(iterations)); 2269 for (int method = 0; method < iterations[m_iteration].methodCount; method++) 2270 (this->*iterations[m_iteration].methods[method])(); 2271 2272 m_iteration++; 2273 2274 if (m_iteration < DE_LENGTH_OF_ARRAY(iterations)) 2275 { 2276 return CONTINUE; 2277 } 2278 else 2279 { 2280 m_state->results.setTestContextResult(m_testCtx); 2281 return STOP; 2282 } 2283 } 2284 2285 class CopyImageTests : public TestCaseGroup 2286 { 2287 public: 2288 CopyImageTests (Context& context); 2289 ~CopyImageTests (void); 2290 2291 void init (void); 2292 2293 private: 2294 CopyImageTests (const CopyImageTests& other); 2295 CopyImageTests& operator= (const CopyImageTests& other); 2296 }; 2297 2298 CopyImageTests::CopyImageTests (Context& context) 2299 : TestCaseGroup (context, "copy_image", "Copy image tests for GL_EXT_copy_image.") 2300 { 2301 } 2302 2303 CopyImageTests::~CopyImageTests (void) 2304 { 2305 } 2306 2307 int smallestCommonMultiple (int a_, int b_) 2308 { 2309 int a = (a_ > b_ ? a_ : b_); 2310 int b = (a_ > b_ ? b_ : a_); 2311 int result = 1; 2312 2313 for (int i = b/2; i > 1; i--) 2314 { 2315 while ((a % i) == 0 && (b % i) == 0) 2316 { 2317 result *= i; 2318 a /= i; 2319 b /= i; 2320 } 2321 } 2322 2323 return result * a * b; 2324 } 2325 2326 IVec3 getTestedSize (deUint32 target, deUint32 format, const IVec3& targetSize) 2327 { 2328 const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(format); 2329 const bool isCube = target == GL_TEXTURE_CUBE_MAP; 2330 const bool is3D = target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY; 2331 2332 if (isCube) 2333 { 2334 const int multiplier = smallestCommonMultiple(texelBlockPixelSize.x(), texelBlockPixelSize.y()); 2335 const int size = (1 + (targetSize.x() / multiplier)) * multiplier; 2336 2337 return IVec3(size, size, 1); 2338 } 2339 else if (is3D) 2340 { 2341 return (1 + (targetSize / texelBlockPixelSize)) * texelBlockPixelSize; 2342 } 2343 else 2344 { 2345 const int width = (1 + targetSize.x() / texelBlockPixelSize.x()) * texelBlockPixelSize.x(); 2346 const int height = ((targetSize.y() / texelBlockPixelSize.y()) - 1) * texelBlockPixelSize.y(); 2347 2348 return IVec3(width, height, 1); 2349 } 2350 } 2351 2352 void addCopyTests (TestCaseGroup* root, deUint32 srcFormat, deUint32 dstFormat) 2353 { 2354 const string groupName = string(formatToName(srcFormat)) + "_" + formatToName(dstFormat); 2355 TestCaseGroup* const group = new TestCaseGroup(root->getContext(), groupName.c_str(), groupName.c_str()); 2356 2357 const deUint32 targets[] = 2358 { 2359 GL_TEXTURE_2D, 2360 GL_TEXTURE_3D, 2361 GL_TEXTURE_CUBE_MAP, 2362 GL_TEXTURE_2D_ARRAY, 2363 GL_RENDERBUFFER 2364 }; 2365 2366 root->addChild(group); 2367 2368 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(targets); srcTargetNdx++) 2369 { 2370 const deUint32 srcTarget = targets[srcTargetNdx]; 2371 const bool srcIs3D = srcTarget == GL_TEXTURE_2D_ARRAY || srcTarget == GL_TEXTURE_3D; 2372 2373 if (glu::isCompressedFormat(srcFormat) && srcTarget == GL_RENDERBUFFER) 2374 continue; 2375 2376 if (srcTarget == GL_RENDERBUFFER && !isColorRenderable(srcFormat)) 2377 continue; 2378 2379 if (glu::isCompressedFormat(srcFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(srcFormat)) && srcIs3D) 2380 continue; 2381 2382 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(targets); dstTargetNdx++) 2383 { 2384 const deUint32 dstTarget = targets[dstTargetNdx]; 2385 const bool dstIs3D = dstTarget == GL_TEXTURE_2D_ARRAY || dstTarget == GL_TEXTURE_3D; 2386 2387 if (glu::isCompressedFormat(dstFormat) && dstTarget == GL_RENDERBUFFER) 2388 continue; 2389 2390 if (dstTarget == GL_RENDERBUFFER && !isColorRenderable(dstFormat)) 2391 continue; 2392 2393 if (glu::isCompressedFormat(dstFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(dstFormat)) && dstIs3D) 2394 continue; 2395 2396 const string targetTestName = string(targetToName(srcTarget)) + "_to_" + targetToName(dstTarget); 2397 2398 // Compressed formats require more space to fit all block size combinations. 2399 const bool isCompressedCase = glu::isCompressedFormat(srcFormat) || glu::isCompressedFormat(dstFormat); 2400 const IVec3 targetSize = isCompressedCase ? IVec3(128, 128, 16) : IVec3(64, 64, 8); 2401 const IVec3 srcSize = getTestedSize(srcTarget, srcFormat, targetSize); 2402 const IVec3 dstSize = getTestedSize(dstTarget, dstFormat, targetSize); 2403 2404 group->addChild(new CopyImageTest(root->getContext(), 2405 ImageInfo(srcFormat, srcTarget, srcSize), 2406 ImageInfo(dstFormat, dstTarget, dstSize), 2407 targetTestName.c_str(), targetTestName.c_str())); 2408 } 2409 } 2410 } 2411 2412 void CopyImageTests::init (void) 2413 { 2414 TestCaseGroup* const nonCompressedGroup = new TestCaseGroup(m_context, "non_compressed", "Test copying between textures."); 2415 TestCaseGroup* const compressedGroup = new TestCaseGroup(m_context, "compressed", "Test copying between compressed textures."); 2416 TestCaseGroup* const mixedGroup = new TestCaseGroup(m_context, "mixed", "Test copying between compressed and non-compressed textures."); 2417 2418 addChild(nonCompressedGroup); 2419 addChild(compressedGroup); 2420 addChild(mixedGroup); 2421 2422 map<ViewClass, vector<deUint32> > textureFormatViewClasses; 2423 map<ViewClass, vector<deUint32> > compressedTextureFormatViewClasses; 2424 map<ViewClass, pair<vector<deUint32>, vector<deUint32> > > mixedViewClasses; 2425 2426 // Texture view classes 2427 textureFormatViewClasses[VIEWCLASS_128_BITS] = vector<deUint32>(); 2428 textureFormatViewClasses[VIEWCLASS_96_BITS] = vector<deUint32>(); 2429 textureFormatViewClasses[VIEWCLASS_64_BITS] = vector<deUint32>(); 2430 textureFormatViewClasses[VIEWCLASS_48_BITS] = vector<deUint32>(); 2431 textureFormatViewClasses[VIEWCLASS_32_BITS] = vector<deUint32>(); 2432 textureFormatViewClasses[VIEWCLASS_24_BITS] = vector<deUint32>(); 2433 textureFormatViewClasses[VIEWCLASS_16_BITS] = vector<deUint32>(); 2434 textureFormatViewClasses[VIEWCLASS_8_BITS] = vector<deUint32>(); 2435 2436 // 128bit / VIEWCLASS_128_BITS 2437 textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32F); 2438 textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32I); 2439 textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32UI); 2440 2441 // 96bit / VIEWCLASS_96_BITS 2442 textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32F); 2443 textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32I); 2444 textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32UI); 2445 2446 // 64bit / VIEWCLASS_64_BITS 2447 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32F); 2448 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32I); 2449 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32UI); 2450 2451 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16F); 2452 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16I); 2453 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16UI); 2454 2455 // 48bit / VIEWCLASS_48_BITS 2456 textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16F); 2457 textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16I); 2458 textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16UI); 2459 2460 // 32bit / VIEWCLASS_32_BITS 2461 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32F); 2462 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32I); 2463 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32UI); 2464 2465 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16F); 2466 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16I); 2467 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16UI); 2468 2469 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8); 2470 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8I); 2471 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8UI); 2472 2473 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R11F_G11F_B10F); 2474 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2UI); 2475 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2); 2476 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8_SNORM); 2477 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_SRGB8_ALPHA8); 2478 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB9_E5); 2479 2480 // 24bit / VIEWCLASS_24_BITS 2481 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8); 2482 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8I); 2483 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8UI); 2484 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8_SNORM); 2485 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_SRGB8); 2486 2487 // 16bit / VIEWCLASS_16_BITS 2488 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16F); 2489 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16I); 2490 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16UI); 2491 2492 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8); 2493 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8I); 2494 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8UI); 2495 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8_SNORM); 2496 2497 // 8bit / VIEWCLASS_8_BITS 2498 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8); 2499 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8I); 2500 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8UI); 2501 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8_SNORM); 2502 2503 // Compressed texture view classes 2504 compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11] = vector<deUint32>(); 2505 compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11] = vector<deUint32>(); 2506 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB] = vector<deUint32>(); 2507 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA] = vector<deUint32>(); 2508 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA] = vector<deUint32>(); 2509 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA] = vector<deUint32>(); 2510 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA] = vector<deUint32>(); 2511 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA] = vector<deUint32>(); 2512 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA] = vector<deUint32>(); 2513 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA] = vector<deUint32>(); 2514 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA] = vector<deUint32>(); 2515 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA] = vector<deUint32>(); 2516 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA] = vector<deUint32>(); 2517 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA] = vector<deUint32>(); 2518 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA] = vector<deUint32>(); 2519 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA] = vector<deUint32>(); 2520 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA] = vector<deUint32>(); 2521 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA] = vector<deUint32>(); 2522 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA] = vector<deUint32>(); 2523 2524 // VIEWCLASS_EAC_R11 2525 compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_R11_EAC); 2526 compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_SIGNED_R11_EAC); 2527 2528 // VIEWCLASS_EAC_RG11 2529 compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_RG11_EAC); 2530 compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_SIGNED_RG11_EAC); 2531 2532 // VIEWCLASS_ETC2_RGB 2533 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_RGB8_ETC2); 2534 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_SRGB8_ETC2); 2535 2536 // VIEWCLASS_ETC2_RGBA 2537 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2); 2538 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); 2539 2540 // VIEWCLASS_ETC2_EAC_RGBA 2541 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); 2542 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); 2543 2544 // VIEWCLASS_ASTC_4x4_RGBA 2545 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_4x4); 2546 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4); 2547 2548 // VIEWCLASS_ASTC_5x4_RGBA 2549 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x4); 2550 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4); 2551 2552 // VIEWCLASS_ASTC_5x5_RGBA 2553 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x5); 2554 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5); 2555 2556 // VIEWCLASS_ASTC_6x5_RGBA 2557 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x5); 2558 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5); 2559 2560 // VIEWCLASS_ASTC_6x6_RGBA 2561 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x6); 2562 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6); 2563 2564 // VIEWCLASS_ASTC_8x5_RGBA 2565 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x5); 2566 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5); 2567 2568 // VIEWCLASS_ASTC_8x6_RGBA 2569 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x6); 2570 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6); 2571 2572 // VIEWCLASS_ASTC_8x8_RGBA 2573 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x8); 2574 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8); 2575 2576 // VIEWCLASS_ASTC_10x5_RGBA 2577 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x5); 2578 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5); 2579 2580 // VIEWCLASS_ASTC_10x6_RGBA 2581 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x6); 2582 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6); 2583 2584 // VIEWCLASS_ASTC_10x8_RGBA 2585 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x8); 2586 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8); 2587 2588 // VIEWCLASS_ASTC_10x10_RGBA 2589 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x10); 2590 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10); 2591 2592 // VIEWCLASS_ASTC_12x10_RGBA 2593 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x10); 2594 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10); 2595 2596 // VIEWCLASS_ASTC_12x12_RGBA 2597 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x12); 2598 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12); 2599 2600 // Mixed view classes 2601 mixedViewClasses[VIEWCLASS_128_BITS] = pair<vector<deUint32>, vector<deUint32> >(); 2602 mixedViewClasses[VIEWCLASS_64_BITS] = pair<vector<deUint32>, vector<deUint32> >(); 2603 2604 // 128 bits 2605 2606 // Non compressed 2607 mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32F); 2608 mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32UI); 2609 mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32I); 2610 2611 // Compressed 2612 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); 2613 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); 2614 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RG11_EAC); 2615 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SIGNED_RG11_EAC); 2616 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_4x4); 2617 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x4); 2618 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x5); 2619 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x5); 2620 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x6); 2621 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x5); 2622 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x6); 2623 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x8); 2624 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x5); 2625 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x6); 2626 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x8); 2627 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x10); 2628 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x10); 2629 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x12); 2630 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4); 2631 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4); 2632 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5); 2633 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5); 2634 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6); 2635 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5); 2636 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6); 2637 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8); 2638 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5); 2639 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6); 2640 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8); 2641 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10); 2642 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10); 2643 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12); 2644 2645 // 64 bits 2646 2647 // Non compressed 2648 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16F); 2649 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16UI); 2650 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16I); 2651 2652 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32F); 2653 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32UI); 2654 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32I); 2655 2656 // Compressed 2657 mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_R11_EAC); 2658 mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_SIGNED_R11_EAC); 2659 2660 for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = textureFormatViewClasses.begin(); viewClassIter != textureFormatViewClasses.end(); ++viewClassIter) 2661 { 2662 const vector<deUint32>& formats = viewClassIter->second; 2663 const ViewClass viewClass = viewClassIter->first; 2664 TestCaseGroup* const viewGroup = new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass)); 2665 2666 nonCompressedGroup->addChild(viewGroup); 2667 2668 for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++) 2669 for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++) 2670 { 2671 const deUint32 srcFormat = formats[srcFormatNdx]; 2672 const deUint32 dstFormat = formats[dstFormatNdx]; 2673 2674 if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat)) 2675 continue; 2676 2677 addCopyTests(viewGroup, srcFormat, dstFormat); 2678 } 2679 } 2680 2681 for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = compressedTextureFormatViewClasses.begin(); viewClassIter != compressedTextureFormatViewClasses.end(); ++viewClassIter) 2682 { 2683 const vector<deUint32>& formats = viewClassIter->second; 2684 const ViewClass viewClass = viewClassIter->first; 2685 TestCaseGroup* const viewGroup = new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass)); 2686 2687 compressedGroup->addChild(viewGroup); 2688 2689 for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++) 2690 for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++) 2691 { 2692 const deUint32 srcFormat = formats[srcFormatNdx]; 2693 const deUint32 dstFormat = formats[dstFormatNdx]; 2694 2695 if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat)) 2696 continue; 2697 2698 addCopyTests(viewGroup, srcFormat, dstFormat); 2699 } 2700 } 2701 2702 for (map<ViewClass, pair<vector<deUint32>, vector<deUint32> > >::const_iterator iter = mixedViewClasses.begin(); iter != mixedViewClasses.end(); ++iter) 2703 { 2704 const ViewClass viewClass = iter->first; 2705 const string viewClassName = string(viewClassToName(viewClass)) + "_mixed"; 2706 TestCaseGroup* const viewGroup = new TestCaseGroup(m_context, viewClassName.c_str(), viewClassName.c_str()); 2707 2708 const vector<deUint32> nonCompressedFormats = iter->second.first; 2709 const vector<deUint32> compressedFormats = iter->second.second; 2710 2711 mixedGroup->addChild(viewGroup); 2712 2713 for (int srcFormatNdx = 0; srcFormatNdx < (int)nonCompressedFormats.size(); srcFormatNdx++) 2714 for (int dstFormatNdx = 0; dstFormatNdx < (int)compressedFormats.size(); dstFormatNdx++) 2715 { 2716 const deUint32 srcFormat = nonCompressedFormats[srcFormatNdx]; 2717 const deUint32 dstFormat = compressedFormats[dstFormatNdx]; 2718 2719 if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat)) 2720 continue; 2721 2722 addCopyTests(viewGroup, srcFormat, dstFormat); 2723 addCopyTests(viewGroup, dstFormat, srcFormat); 2724 } 2725 } 2726 } 2727 2728 } // anonymous 2729 2730 TestCaseGroup* createCopyImageTests (Context& context) 2731 { 2732 return new CopyImageTests(context); 2733 } 2734 2735 } // Functional 2736 } // gles31 2737 } // deqp 2738