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 62using namespace deqp::gls::TextureTestUtil; 63using namespace glu::TextureTestUtil; 64 65using tcu::Float; 66using tcu::IVec2; 67using tcu::IVec3; 68using tcu::IVec4; 69using tcu::Sampler; 70using tcu::ScopedLogSection; 71using tcu::TestLog; 72using tcu::Vec4; 73using tcu::SeedBuilder; 74 75using de::ArrayBuffer; 76 77using std::map; 78using std::string; 79using std::vector; 80using std::pair; 81 82namespace deqp 83{ 84namespace gles31 85{ 86namespace Functional 87{ 88namespace 89{ 90 91enum 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 123enum Verify 124{ 125 VERIFY_NONE = 0, 126 VERIFY_COMPARE_REFERENCE 127}; 128 129const 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 167const 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 183string 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 195bool 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 203bool 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 211bool 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 219bool 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 231bool isTextureTarget (deUint32 target) 232{ 233 return target != GL_RENDERBUFFER; 234} 235 236int 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 260class RandomizedRenderGrid 261{ 262public: 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 271private: 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 282RandomizedRenderGrid::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 293IVec2 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 316bool RandomizedRenderGrid::nextCell (void) 317{ 318 if (m_currentCell >= getCellCount()) 319 return false; 320 321 m_currentCell++; 322 return true; 323} 324 325IVec2 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 337IVec4 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 345class ImageInfo 346{ 347public: 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 354private: 355 deUint32 m_format; 356 deUint32 m_target; 357 IVec3 m_size; 358}; 359 360ImageInfo::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 370SeedBuilder& operator<< (SeedBuilder& builder, const ImageInfo& info) 371{ 372 builder << info.getFormat() << info.getTarget() << info.getSize(); 373 return builder; 374} 375 376const 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 384int 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 405IVec3 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 425deUint32 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. 443class TextureImageIterator 444{ 445public: 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 460private: 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 469TextureImageIterator::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 480bool 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 504string 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 523string 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 543void 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. 573struct 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. 582deUint32 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 614int 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 622IVec3 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 630bool 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 669deUint32 getTypeForInternalFormat (deUint32 format) 670{ 671 return glu::getTransferFormat(glu::mapGLInternalFormat(format)).dataType; 672} 673 674void 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 744IVec3 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 754deUint32 getFormatForInternalFormat (deUint32 format) 755{ 756 return glu::getTransferFormat(glu::mapGLInternalFormat(format)).format; 757} 758 759void 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 815void 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 868void 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 971void 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 984IVec3 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 994int 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 1004void 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 1055vector<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 1074vector<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 1100void 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 1126template<class TextureView> 1127void 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 1222void 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 1261void 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 1275void 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 1312void 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 1344void 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 1384void 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 1416void 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 1456void 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 1550void 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 1589void 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 1621tcu::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 1642Vec4 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 const tcu::IVec4 minBits = tcu::min(srcBits, readBits); 1657 1658 return Vec4( 1659 minBits[0] ? 1.0f / (float)((1 << minBits[0]) - 1) : 0, 1660 minBits[1] ? 1.0f / (float)((1 << minBits[1]) - 1) : 0, 1661 minBits[2] ? 1.0f / (float)((1 << minBits[2]) - 1) : 0, 1662 minBits[3] ? 1.0f / (float)((1 << minBits[3]) - 1) : 0); 1663 } 1664} 1665 1666void renderRenderbuffer (tcu::TestContext& testContext, 1667 glu::RenderContext& renderContext, 1668 tcu::ResultCollector& results, 1669 deUint32 name, 1670 const vector<ArrayBuffer<deUint8> >& data, 1671 const ImageInfo& info, 1672 Verify verify) 1673{ 1674 const glw::Functions& gl = renderContext.getFunctions(); 1675 TestLog& log = testContext.getLog(); 1676 1677 const tcu::TextureFormat format = glu::mapGLInternalFormat(info.getFormat()); 1678 const IVec3 size = info.getSize(); 1679 const tcu::ConstPixelBufferAccess refRenderbuffer (format, size.x(), size.y(), 1, data[0].getPtr()); 1680 const tcu::TextureFormat readPixelsFormat = getReadPixelFormat(format); 1681 tcu::TextureLevel renderbuffer (readPixelsFormat, size.x(), size.y()); 1682 1683 DE_ASSERT(size.z() == 1); 1684 DE_ASSERT(data.size() == 1); 1685 1686 { 1687 glu::Framebuffer framebuffer(gl); 1688 1689 gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer); 1690 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create and bind framebuffer."); 1691 1692 gl.bindRenderbuffer(GL_RENDERBUFFER, name); 1693 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name); 1694 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind and attach renderbuffer to framebuffer."); 1695 1696 if (verify) 1697 glu::readPixels(renderContext, 0, 0, renderbuffer.getAccess()); 1698 1699 gl.bindRenderbuffer(GL_RENDERBUFFER, 0); 1700 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1701 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbuffer and framebuffer."); 1702 } 1703 1704 if (verify == VERIFY_COMPARE_REFERENCE) 1705 { 1706 if (isFloatFormat(info.getFormat())) 1707 { 1708 const tcu::UVec4 threshold (2, 2, 2, 2); 1709 1710 if (!(tcu::floatUlpThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR))) 1711 results.fail("Image comparison failed."); 1712 else 1713 log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage; 1714 } 1715 else if (isIntFormat(info.getFormat()) || isUintFormat(info.getFormat())) 1716 { 1717 const tcu::UVec4 threshold (1, 1, 1, 1); 1718 1719 if (!(tcu::intThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR))) 1720 results.fail("Image comparison failed."); 1721 else 1722 log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage; 1723 } 1724 else 1725 { 1726 const Vec4 threshold = calculateThreshold(format, readPixelsFormat); 1727 1728 if (!(tcu::floatThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR))) 1729 results.fail("Image comparison failed."); 1730 else 1731 log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage; 1732 } 1733 } 1734} 1735 1736void render (tcu::TestContext& testContext, 1737 glu::RenderContext& renderContext, 1738 TextureRenderer& textureRenderer, 1739 tcu::ResultCollector& results, 1740 de::Random& rng, 1741 deUint32 name, 1742 const vector<ArrayBuffer<deUint8> >& data, 1743 const ImageInfo& info, 1744 Verify verify) 1745{ 1746 switch (info.getTarget()) 1747 { 1748 case GL_TEXTURE_2D: 1749 renderTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1750 break; 1751 1752 case GL_TEXTURE_3D: 1753 renderTexture3D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1754 break; 1755 1756 case GL_TEXTURE_CUBE_MAP: 1757 renderTextureCubemap(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1758 break; 1759 1760 case GL_TEXTURE_2D_ARRAY: 1761 renderTexture2DArray(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify); 1762 break; 1763 1764 case GL_RENDERBUFFER: 1765 renderRenderbuffer(testContext, renderContext, results, name, data, info, verify); 1766 break; 1767 1768 default: 1769 DE_ASSERT(false); 1770 } 1771} 1772 1773void logTestImageInfo (TestLog& log, 1774 const ImageInfo& imageInfo) 1775{ 1776 log << TestLog::Message << "Target: " << targetToName(imageInfo.getTarget()) << TestLog::EndMessage; 1777 log << TestLog::Message << "Size: " << imageInfo.getSize() << TestLog::EndMessage; 1778 log << TestLog::Message << "Levels: " << getLevelCount(imageInfo) << TestLog::EndMessage; 1779 log << TestLog::Message << "Format: " << formatToName(imageInfo.getFormat()) << TestLog::EndMessage; 1780} 1781 1782void logTestInfo (TestLog& log, 1783 const ImageInfo& srcImageInfo, 1784 const ImageInfo& dstImageInfo) 1785{ 1786 tcu::ScopedLogSection section(log, "TestCaseInfo", "Test case info"); 1787 1788 log << TestLog::Message << "Testing copying from " << targetToName(srcImageInfo.getTarget()) << " to " << targetToName(dstImageInfo.getTarget()) << "." << TestLog::EndMessage; 1789 1790 { 1791 tcu::ScopedLogSection srcSection(log, "Source image info.", "Source image info."); 1792 logTestImageInfo(log, srcImageInfo); 1793 } 1794 1795 { 1796 tcu::ScopedLogSection dstSection(log, "Destination image info.", "Destination image info."); 1797 logTestImageInfo(log, dstImageInfo); 1798 } 1799} 1800 1801class CopyImageTest : public TestCase 1802{ 1803public: 1804 CopyImageTest (Context& context, 1805 const ImageInfo& srcImage, 1806 const ImageInfo& dstImage, 1807 const char* name, 1808 const char* description); 1809 1810 ~CopyImageTest (void); 1811 1812 void init (void); 1813 void deinit (void); 1814 1815 TestCase::IterateResult iterate (void); 1816 1817private: 1818 1819 void logTestInfoIter (void); 1820 void createImagesIter (void); 1821 void destroyImagesIter (void); 1822 void verifySourceIter (void); 1823 void verifyDestinationIter (void); 1824 void renderSourceIter (void); 1825 void renderDestinationIter (void); 1826 void copyImageIter (void); 1827 1828 typedef void (CopyImageTest::*IterationFunc)(void); 1829 1830 struct Iteration 1831 { 1832 Iteration (int methodCount_, const IterationFunc* methods_) 1833 : methodCount (methodCount_) 1834 , methods (methods_) 1835 { 1836 } 1837 1838 int methodCount; 1839 const IterationFunc* methods; 1840 }; 1841 1842 struct State 1843 { 1844 State (int seed, 1845 tcu::TestLog& log, 1846 glu::RenderContext& renderContext) 1847 : rng (seed) 1848 , results (log) 1849 , srcImage (NULL) 1850 , dstImage (NULL) 1851 , textureRenderer (renderContext, log, glu::getContextTypeGLSLVersion(renderContext.getType()), glu::PRECISION_HIGHP) 1852 { 1853 } 1854 1855 ~State (void) 1856 { 1857 delete srcImage; 1858 delete dstImage; 1859 } 1860 1861 de::Random rng; 1862 tcu::ResultCollector results; 1863 glu::ObjectWrapper* srcImage; 1864 glu::ObjectWrapper* dstImage; 1865 TextureRenderer textureRenderer; 1866 1867 vector<ArrayBuffer<deUint8> > srcImageLevels; 1868 vector<ArrayBuffer<deUint8> > dstImageLevels; 1869 }; 1870 1871 const ImageInfo m_srcImageInfo; 1872 const ImageInfo m_dstImageInfo; 1873 1874 int m_iteration; 1875 State* m_state; 1876}; 1877 1878CopyImageTest::CopyImageTest (Context& context, 1879 const ImageInfo& srcImage, 1880 const ImageInfo& dstImage, 1881 const char* name, 1882 const char* description) 1883 : TestCase (context, name, description) 1884 , m_srcImageInfo (srcImage) 1885 , m_dstImageInfo (dstImage) 1886 1887 , m_iteration (0) 1888 , m_state (NULL) 1889{ 1890} 1891 1892CopyImageTest::~CopyImageTest (void) 1893{ 1894 deinit(); 1895} 1896 1897void checkFormatSupport (glu::ContextInfo& info, deUint32 format, deUint32 target, glu::RenderContext& ctx) 1898{ 1899 const bool isES32 = glu::contextSupports(ctx.getType(), glu::ApiType::es(3, 2)); 1900 1901 if (glu::isCompressedFormat(format)) 1902 { 1903 if (isAstcFormat(glu::mapGLCompressedTexFormat(format))) 1904 { 1905 DE_ASSERT(target != GL_RENDERBUFFER); 1906 if (!info.isExtensionSupported("GL_KHR_texture_compression_astc_sliced_3d") && 1907 !info.isExtensionSupported("GL_KHR_texture_compression_astc_hdr") && 1908 !info.isExtensionSupported("GL_OES_texture_compression_astc")) 1909 { 1910 if (target == GL_TEXTURE_3D) 1911 TCU_THROW(NotSupportedError, "TEXTURE_3D target not supported."); 1912 if (!isES32 && !info.isExtensionSupported("GL_KHR_texture_compression_astc_ldr")) 1913 TCU_THROW(NotSupportedError, "Compressed astc texture not supported."); 1914 } 1915 } 1916 else 1917 { 1918 if (!info.isCompressedTextureFormatSupported(format)) 1919 TCU_THROW(NotSupportedError, "Compressed texture not supported."); 1920 } 1921 } 1922} 1923 1924void CopyImageTest::init (void) 1925{ 1926 auto& rc = m_context.getRenderContext(); 1927 de::UniquePtr<glu::ContextInfo> ctxInfo (glu::ContextInfo::create(rc)); 1928 const bool isES32orGL45 = glu::contextSupports(rc.getType(), glu::ApiType::es(3, 2)) || 1929 glu::contextSupports(rc.getType(), glu::ApiType::core(4, 5)); 1930 1931 if (!isES32orGL45 && !ctxInfo->isExtensionSupported("GL_EXT_copy_image")) 1932 throw tcu::NotSupportedError("Extension GL_EXT_copy_image not supported.", "", __FILE__, __LINE__); 1933 1934 checkFormatSupport(*ctxInfo, m_srcImageInfo.getFormat(), m_srcImageInfo.getTarget(), rc); 1935 checkFormatSupport(*ctxInfo, m_dstImageInfo.getFormat(), m_dstImageInfo.getTarget(), rc); 1936 1937 { 1938 SeedBuilder builder; 1939 1940 builder << 903980 1941 << m_srcImageInfo 1942 << m_dstImageInfo; 1943 1944 m_state = new State(builder.get(), m_testCtx.getLog(), rc); 1945 } 1946} 1947 1948void CopyImageTest::deinit (void) 1949{ 1950 delete m_state; 1951 m_state = NULL; 1952} 1953 1954void CopyImageTest::logTestInfoIter (void) 1955{ 1956 TestLog& log = m_testCtx.getLog(); 1957 1958 logTestInfo(log, m_srcImageInfo, m_dstImageInfo); 1959} 1960 1961void CopyImageTest::createImagesIter (void) 1962{ 1963 TestLog& log = m_testCtx.getLog(); 1964 glu::RenderContext& renderContext = m_context.getRenderContext(); 1965 const glw::Functions& gl = renderContext.getFunctions(); 1966 const deUint32 moreRestrictiveFormat = getMoreRestrictiveFormat(m_srcImageInfo.getFormat(), m_dstImageInfo.getFormat()); 1967 de::Random& rng = m_state->rng; 1968 1969 DE_ASSERT(!m_state->srcImage); 1970 DE_ASSERT(!m_state->dstImage); 1971 1972 m_state->srcImage = new glu::ObjectWrapper(gl, getObjectTraits(m_srcImageInfo)); 1973 m_state->dstImage = new glu::ObjectWrapper(gl, getObjectTraits(m_dstImageInfo)); 1974 1975 { 1976 glu::ObjectWrapper& srcImage = *m_state->srcImage; 1977 glu::ObjectWrapper& dstImage = *m_state->dstImage; 1978 1979 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 1980 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 1981 1982 log << TestLog::Message << "Creating source image." << TestLog::EndMessage; 1983 genImage(gl, rng, *srcImage, srcImageLevels, m_srcImageInfo, moreRestrictiveFormat); 1984 1985 log << TestLog::Message << "Creating destination image." << TestLog::EndMessage; 1986 genImage(gl, rng, *dstImage, dstImageLevels, m_dstImageInfo, moreRestrictiveFormat); 1987 } 1988} 1989 1990void CopyImageTest::destroyImagesIter (void) 1991{ 1992 TestLog& log = m_testCtx.getLog(); 1993 1994 log << TestLog::Message << "Deleting source image. " << TestLog::EndMessage; 1995 1996 delete m_state->srcImage; 1997 m_state->srcImage = NULL; 1998 m_state->srcImageLevels.clear(); 1999 2000 log << TestLog::Message << "Deleting destination image. " << TestLog::EndMessage; 2001 2002 delete m_state->dstImage; 2003 m_state->dstImage = NULL; 2004 m_state->dstImageLevels.clear(); 2005} 2006 2007void CopyImageTest::verifySourceIter (void) 2008{ 2009 TestLog& log = m_testCtx.getLog(); 2010 const tcu::ScopedLogSection sourceSection (log, "Source image verify.", "Source image verify."); 2011 2012 de::Random& rng = m_state->rng; 2013 tcu::ResultCollector& results = m_state->results; 2014 glu::ObjectWrapper& srcImage = *m_state->srcImage; 2015 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 2016 2017 log << TestLog::Message << "Verifying source image." << TestLog::EndMessage; 2018 2019 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_COMPARE_REFERENCE); 2020} 2021 2022void CopyImageTest::verifyDestinationIter (void) 2023{ 2024 TestLog& log = m_testCtx.getLog(); 2025 const tcu::ScopedLogSection destinationSection (log, "Destination image verify.", "Destination image verify."); 2026 2027 de::Random& rng = m_state->rng; 2028 tcu::ResultCollector& results = m_state->results; 2029 glu::ObjectWrapper& dstImage = *m_state->dstImage; 2030 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 2031 2032 log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage; 2033 2034 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_COMPARE_REFERENCE); 2035} 2036 2037void CopyImageTest::renderSourceIter (void) 2038{ 2039 TestLog& log = m_testCtx.getLog(); 2040 const tcu::ScopedLogSection sourceSection (log, "Source image verify.", "Source image verify."); 2041 2042 de::Random& rng = m_state->rng; 2043 tcu::ResultCollector& results = m_state->results; 2044 glu::ObjectWrapper& srcImage = *m_state->srcImage; 2045 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 2046 2047 log << TestLog::Message << "Verifying source image." << TestLog::EndMessage; 2048 2049 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_NONE); 2050} 2051 2052void CopyImageTest::renderDestinationIter (void) 2053{ 2054 TestLog& log = m_testCtx.getLog(); 2055 const tcu::ScopedLogSection destinationSection (log, "Destination image verify.", "Destination image verify."); 2056 2057 de::Random& rng = m_state->rng; 2058 tcu::ResultCollector& results = m_state->results; 2059 glu::ObjectWrapper& dstImage = *m_state->dstImage; 2060 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 2061 2062 log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage; 2063 2064 render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_NONE); 2065} 2066 2067struct Copy 2068{ 2069 Copy (const IVec3& srcPos_, 2070 int srcLevel_, 2071 2072 const IVec3& dstPos_, 2073 int dstLevel_, 2074 2075 const IVec3& size_, 2076 const IVec3& dstSize_) 2077 : srcPos (srcPos_) 2078 , srcLevel (srcLevel_) 2079 2080 , dstPos (dstPos_) 2081 , dstLevel (dstLevel_) 2082 2083 , size (size_) 2084 , dstSize (dstSize_) 2085 { 2086 } 2087 2088 IVec3 srcPos; 2089 int srcLevel; 2090 IVec3 dstPos; 2091 int dstLevel; 2092 IVec3 size; 2093 IVec3 dstSize; //!< used only for logging 2094}; 2095 2096int getLastFullLevel (const ImageInfo& info) 2097{ 2098 const int levelCount = getLevelCount(info); 2099 const IVec3 blockPixelSize = getTexelBlockPixelSize(info.getFormat()); 2100 2101 for (int level = 0; level < levelCount; level++) 2102 { 2103 const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level); 2104 2105 if (levelSize.x() < blockPixelSize.x() || levelSize.y() < blockPixelSize.y() || levelSize.z() < blockPixelSize.z()) 2106 return level - 1; 2107 } 2108 2109 return levelCount -1; 2110} 2111 2112void generateCopies (vector<Copy>& copies, const ImageInfo& srcInfo, const ImageInfo& dstInfo) 2113{ 2114 const deUint32 srcTarget = srcInfo.getTarget(); 2115 const deUint32 dstTarget = dstInfo.getTarget(); 2116 2117 const bool srcIsTexture = isTextureTarget(srcInfo.getTarget()); 2118 const bool dstIsTexture = isTextureTarget(dstInfo.getTarget()); 2119 2120 const bool srcIsCube = srcTarget == GL_TEXTURE_CUBE_MAP; 2121 const bool dstIsCube = dstTarget == GL_TEXTURE_CUBE_MAP; 2122 2123 const IVec3 srcBlockPixelSize = getTexelBlockPixelSize(srcInfo.getFormat()); 2124 const IVec3 dstBlockPixelSize = getTexelBlockPixelSize(dstInfo.getFormat()); 2125 2126 const int levels[] = 2127 { 2128 0, 1, -1 2129 }; 2130 2131 for (int levelNdx = 0; levelNdx < (srcIsTexture || dstIsTexture ? DE_LENGTH_OF_ARRAY(levels) : 1); levelNdx++) 2132 { 2133 const int srcLevel = (srcIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(srcInfo)) : 0); 2134 const int dstLevel = (dstIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(dstInfo)) : 0); 2135 2136 const IVec3 srcSize = getLevelSize(srcInfo.getTarget(), srcInfo.getSize(), srcLevel); 2137 const IVec3 dstSize = getLevelSize(dstInfo.getTarget(), dstInfo.getSize(), dstLevel); 2138 2139 // \note These are rounded down 2140 const IVec3 srcCompleteBlockSize = IVec3(srcSize.x() / srcBlockPixelSize.x(), srcSize.y() / srcBlockPixelSize.y(), (srcIsCube ? 6 : srcSize.z() / srcBlockPixelSize.z())); 2141 const IVec3 dstCompleteBlockSize = IVec3(dstSize.x() / dstBlockPixelSize.x(), dstSize.y() / dstBlockPixelSize.y(), (dstIsCube ? 6 : dstSize.z() / dstBlockPixelSize.z())); 2142 2143 const IVec3 maxCopyBlockSize = tcu::min(srcCompleteBlockSize, dstCompleteBlockSize); 2144 2145 // \note These are rounded down 2146 const int copyBlockWidth = de::max((2 * (maxCopyBlockSize.x() / 4)) - 1, 1); 2147 const int copyBlockHeight = de::max((2 * (maxCopyBlockSize.y() / 4)) - 1, 1); 2148 const int copyBlockDepth = de::max((2 * (maxCopyBlockSize.z() / 4)) - 1, 1); 2149 2150 // Copy NPOT block to (0,0,0) from other corner on src 2151 { 2152 const IVec3 copyBlockSize (copyBlockWidth, copyBlockHeight, copyBlockDepth); 2153 const IVec3 srcBlockPos (srcCompleteBlockSize - copyBlockSize); 2154 const IVec3 dstBlockPos (0, 0, 0); 2155 2156 const IVec3 srcPos (srcBlockPos * srcBlockPixelSize); 2157 const IVec3 dstPos (dstBlockPos * dstBlockPixelSize); 2158 const IVec3 srcCopySize (copyBlockSize * srcBlockPixelSize); 2159 const IVec3 dstCopySize (copyBlockSize * dstBlockPixelSize); 2160 2161 copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize)); 2162 } 2163 2164 // Copy NPOT block from (0,0,0) to other corner on dst 2165 { 2166 const IVec3 copyBlockSize (copyBlockWidth, copyBlockHeight, copyBlockDepth); 2167 const IVec3 srcBlockPos (0, 0, 0); 2168 const IVec3 dstBlockPos (dstCompleteBlockSize - copyBlockSize); 2169 2170 const IVec3 srcPos (srcBlockPos * srcBlockPixelSize); 2171 const IVec3 dstPos (dstBlockPos * dstBlockPixelSize); 2172 const IVec3 srcCopySize (copyBlockSize * srcBlockPixelSize); 2173 const IVec3 dstCopySize (copyBlockSize * dstBlockPixelSize); 2174 2175 copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize)); 2176 } 2177 2178 // Copy NPOT block near the corner with high coordinates 2179 { 2180 const IVec3 copyBlockSize (copyBlockWidth, copyBlockHeight, copyBlockDepth); 2181 const IVec3 srcBlockPos (tcu::max((srcCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0))); 2182 const IVec3 dstBlockPos (tcu::max((dstCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0))); 2183 2184 const IVec3 srcPos (srcBlockPos * srcBlockPixelSize); 2185 const IVec3 dstPos (dstBlockPos * dstBlockPixelSize); 2186 const IVec3 srcCopySize (copyBlockSize * srcBlockPixelSize); 2187 const IVec3 dstCopySize (copyBlockSize * dstBlockPixelSize); 2188 2189 copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize)); 2190 } 2191 } 2192} 2193 2194void CopyImageTest::copyImageIter (void) 2195{ 2196 TestLog& log = m_testCtx.getLog(); 2197 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2198 glu::ObjectWrapper& srcImage = *m_state->srcImage; 2199 glu::ObjectWrapper& dstImage = *m_state->dstImage; 2200 2201 vector<ArrayBuffer<deUint8> >& srcImageLevels = m_state->srcImageLevels; 2202 vector<ArrayBuffer<deUint8> >& dstImageLevels = m_state->dstImageLevels; 2203 vector<Copy> copies; 2204 2205 generateCopies(copies, m_srcImageInfo, m_dstImageInfo); 2206 2207 for (int copyNdx = 0; copyNdx < (int)copies.size(); copyNdx++) 2208 { 2209 const Copy& copy = copies[copyNdx]; 2210 2211 log << TestLog::Message 2212 << "Copying area with size " << copy.size 2213 << " from source image position " << copy.srcPos << " and mipmap level " << copy.srcLevel 2214 << " to destination image position " << copy.dstPos << " and mipmap level " << copy.dstLevel << ". " 2215 << "Size in destination format is " << copy.dstSize 2216 << TestLog::EndMessage; 2217 2218 copyImage(gl, *dstImage, dstImageLevels, m_dstImageInfo, copy.dstLevel, copy.dstPos, 2219 *srcImage, srcImageLevels, m_srcImageInfo, copy.srcLevel, copy.srcPos, copy.size); 2220 } 2221} 2222 2223TestCase::IterateResult CopyImageTest::iterate (void) 2224{ 2225 // Note: Returning from iterate() has two side-effects: it touches 2226 // watchdog and calls eglSwapBuffers. For the first it's important 2227 // to keep work per iteration reasonable to avoid 2228 // timeouts. Because of the latter, it's prudent to do more than 2229 // trivial amount of work. Otherwise we'll end up waiting for a 2230 // new buffer in swap, it seems. 2231 2232 // The split below tries to combine trivial work with actually 2233 // expensive rendering iterations without having too much 2234 // rendering in one iteration to avoid timeouts. 2235 const IterationFunc iteration1[] = 2236 { 2237 &CopyImageTest::logTestInfoIter, 2238 &CopyImageTest::createImagesIter, 2239 &CopyImageTest::renderSourceIter 2240 }; 2241 const IterationFunc iteration2[] = 2242 { 2243 &CopyImageTest::renderDestinationIter 2244 }; 2245 const IterationFunc iteration3[] = 2246 { 2247 &CopyImageTest::copyImageIter, 2248 &CopyImageTest::verifySourceIter 2249 }; 2250 const IterationFunc iteration4[] = 2251 { 2252 &CopyImageTest::verifyDestinationIter, 2253 &CopyImageTest::destroyImagesIter 2254 }; 2255 const IterationFunc iteration5[] = 2256 { 2257 &CopyImageTest::createImagesIter, 2258 &CopyImageTest::copyImageIter, 2259 &CopyImageTest::verifySourceIter 2260 }; 2261 const IterationFunc iteration6[] = 2262 { 2263 &CopyImageTest::verifyDestinationIter, 2264 &CopyImageTest::destroyImagesIter 2265 }; 2266 const Iteration iterations[] = 2267 { 2268 Iteration(DE_LENGTH_OF_ARRAY(iteration1), iteration1), 2269 Iteration(DE_LENGTH_OF_ARRAY(iteration2), iteration2), 2270 Iteration(DE_LENGTH_OF_ARRAY(iteration3), iteration3), 2271 Iteration(DE_LENGTH_OF_ARRAY(iteration4), iteration4), 2272 Iteration(DE_LENGTH_OF_ARRAY(iteration5), iteration5), 2273 Iteration(DE_LENGTH_OF_ARRAY(iteration6), iteration6) 2274 }; 2275 2276 DE_ASSERT(m_iteration < DE_LENGTH_OF_ARRAY(iterations)); 2277 for (int method = 0; method < iterations[m_iteration].methodCount; method++) 2278 (this->*iterations[m_iteration].methods[method])(); 2279 2280 m_iteration++; 2281 2282 if (m_iteration < DE_LENGTH_OF_ARRAY(iterations)) 2283 { 2284 return CONTINUE; 2285 } 2286 else 2287 { 2288 m_state->results.setTestContextResult(m_testCtx); 2289 return STOP; 2290 } 2291} 2292 2293class CopyImageTests : public TestCaseGroup 2294{ 2295public: 2296 CopyImageTests (Context& context, bool is_GL45); 2297 ~CopyImageTests (void); 2298 2299 void init (void); 2300 2301private: 2302 CopyImageTests (const CopyImageTests& other); 2303 CopyImageTests& operator= (const CopyImageTests& other); 2304 bool m_isGL45; 2305}; 2306 2307CopyImageTests::CopyImageTests (Context& context, bool is_GL45) 2308 : TestCaseGroup (context, "copy_image", "Copy image tests for GL_EXT_copy_image.") 2309 , m_isGL45 (is_GL45) 2310{ 2311} 2312 2313CopyImageTests::~CopyImageTests (void) 2314{ 2315} 2316 2317int smallestCommonMultiple (int a_, int b_) 2318{ 2319 int a = (a_ > b_ ? a_ : b_); 2320 int b = (a_ > b_ ? b_ : a_); 2321 int result = 1; 2322 2323 for (int i = b/2; i > 1; i--) 2324 { 2325 while ((a % i) == 0 && (b % i) == 0) 2326 { 2327 result *= i; 2328 a /= i; 2329 b /= i; 2330 } 2331 } 2332 2333 return result * a * b; 2334} 2335 2336IVec3 getTestedSize (deUint32 target, deUint32 format, const IVec3& targetSize) 2337{ 2338 const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(format); 2339 const bool isCube = target == GL_TEXTURE_CUBE_MAP; 2340 const bool is3D = target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY; 2341 2342 if (isCube) 2343 { 2344 const int multiplier = smallestCommonMultiple(texelBlockPixelSize.x(), texelBlockPixelSize.y()); 2345 const int size = (1 + (targetSize.x() / multiplier)) * multiplier; 2346 2347 return IVec3(size, size, 1); 2348 } 2349 else if (is3D) 2350 { 2351 return (1 + (targetSize / texelBlockPixelSize)) * texelBlockPixelSize; 2352 } 2353 else 2354 { 2355 const int width = (1 + targetSize.x() / texelBlockPixelSize.x()) * texelBlockPixelSize.x(); 2356 const int height = ((targetSize.y() / texelBlockPixelSize.y()) - 1) * texelBlockPixelSize.y(); 2357 2358 return IVec3(width, height, 1); 2359 } 2360} 2361 2362void addCopyTests (TestCaseGroup* root, deUint32 srcFormat, deUint32 dstFormat) 2363{ 2364 const string groupName = string(formatToName(srcFormat)) + "_" + formatToName(dstFormat); 2365 TestCaseGroup* const group = new TestCaseGroup(root->getContext(), groupName.c_str(), groupName.c_str()); 2366 2367 const deUint32 targets[] = 2368 { 2369 GL_TEXTURE_2D, 2370 GL_TEXTURE_3D, 2371 GL_TEXTURE_CUBE_MAP, 2372 GL_TEXTURE_2D_ARRAY, 2373 GL_RENDERBUFFER 2374 }; 2375 2376 root->addChild(group); 2377 2378 for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(targets); srcTargetNdx++) 2379 { 2380 const deUint32 srcTarget = targets[srcTargetNdx]; 2381 const bool srcIs3D = srcTarget == GL_TEXTURE_2D_ARRAY || srcTarget == GL_TEXTURE_3D; 2382 2383 if (glu::isCompressedFormat(srcFormat) && srcTarget == GL_RENDERBUFFER) 2384 continue; 2385 2386 if (srcTarget == GL_RENDERBUFFER && !isColorRenderable(srcFormat)) 2387 continue; 2388 2389 if (glu::isCompressedFormat(srcFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(srcFormat)) && srcIs3D) 2390 continue; 2391 2392 for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(targets); dstTargetNdx++) 2393 { 2394 const deUint32 dstTarget = targets[dstTargetNdx]; 2395 const bool dstIs3D = dstTarget == GL_TEXTURE_2D_ARRAY || dstTarget == GL_TEXTURE_3D; 2396 2397 if (glu::isCompressedFormat(dstFormat) && dstTarget == GL_RENDERBUFFER) 2398 continue; 2399 2400 if (dstTarget == GL_RENDERBUFFER && !isColorRenderable(dstFormat)) 2401 continue; 2402 2403 if (glu::isCompressedFormat(dstFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(dstFormat)) && dstIs3D) 2404 continue; 2405 2406 const string targetTestName = string(targetToName(srcTarget)) + "_to_" + targetToName(dstTarget); 2407 2408 // Compressed formats require more space to fit all block size combinations. 2409 const bool isCompressedCase = glu::isCompressedFormat(srcFormat) || glu::isCompressedFormat(dstFormat); 2410 const IVec3 targetSize = isCompressedCase ? IVec3(128, 128, 16) : IVec3(64, 64, 8); 2411 const IVec3 srcSize = getTestedSize(srcTarget, srcFormat, targetSize); 2412 const IVec3 dstSize = getTestedSize(dstTarget, dstFormat, targetSize); 2413 2414 group->addChild(new CopyImageTest(root->getContext(), 2415 ImageInfo(srcFormat, srcTarget, srcSize), 2416 ImageInfo(dstFormat, dstTarget, dstSize), 2417 targetTestName.c_str(), targetTestName.c_str())); 2418 } 2419 } 2420} 2421 2422void CopyImageTests::init (void) 2423{ 2424 map<ViewClass, vector<deUint32> > textureFormatViewClasses; 2425 map<ViewClass, vector<deUint32> > compressedTextureFormatViewClasses; 2426 map<ViewClass, pair<vector<deUint32>, vector<deUint32> > > mixedViewClasses; 2427 2428 // Texture view classes 2429 textureFormatViewClasses[VIEWCLASS_128_BITS] = vector<deUint32>(); 2430 textureFormatViewClasses[VIEWCLASS_96_BITS] = vector<deUint32>(); 2431 textureFormatViewClasses[VIEWCLASS_64_BITS] = vector<deUint32>(); 2432 textureFormatViewClasses[VIEWCLASS_48_BITS] = vector<deUint32>(); 2433 textureFormatViewClasses[VIEWCLASS_32_BITS] = vector<deUint32>(); 2434 textureFormatViewClasses[VIEWCLASS_24_BITS] = vector<deUint32>(); 2435 textureFormatViewClasses[VIEWCLASS_16_BITS] = vector<deUint32>(); 2436 textureFormatViewClasses[VIEWCLASS_8_BITS] = vector<deUint32>(); 2437 2438 // 128bit / VIEWCLASS_128_BITS 2439 textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32F); 2440 textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32I); 2441 textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32UI); 2442 2443 // 96bit / VIEWCLASS_96_BITS 2444 textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32F); 2445 textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32I); 2446 textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32UI); 2447 2448 // 64bit / VIEWCLASS_64_BITS 2449 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32F); 2450 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32I); 2451 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32UI); 2452 2453 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16F); 2454 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16I); 2455 textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16UI); 2456 2457 // 48bit / VIEWCLASS_48_BITS 2458 textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16F); 2459 textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16I); 2460 textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16UI); 2461 2462 // 32bit / VIEWCLASS_32_BITS 2463 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32F); 2464 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32I); 2465 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32UI); 2466 2467 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16F); 2468 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16I); 2469 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16UI); 2470 2471 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8); 2472 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8I); 2473 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8UI); 2474 2475 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R11F_G11F_B10F); 2476 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2UI); 2477 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2); 2478 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8_SNORM); 2479 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_SRGB8_ALPHA8); 2480 textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB9_E5); 2481 2482 // 24bit / VIEWCLASS_24_BITS 2483 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8); 2484 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8I); 2485 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8UI); 2486 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8_SNORM); 2487 textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_SRGB8); 2488 2489 // 16bit / VIEWCLASS_16_BITS 2490 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16F); 2491 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16I); 2492 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16UI); 2493 2494 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8); 2495 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8I); 2496 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8UI); 2497 textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8_SNORM); 2498 2499 // 8bit / VIEWCLASS_8_BITS 2500 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8); 2501 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8I); 2502 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8UI); 2503 textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8_SNORM); 2504 2505 // Compressed texture view classes 2506 compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11] = vector<deUint32>(); 2507 compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11] = vector<deUint32>(); 2508 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB] = vector<deUint32>(); 2509 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA] = vector<deUint32>(); 2510 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA] = vector<deUint32>(); 2511 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA] = vector<deUint32>(); 2512 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA] = vector<deUint32>(); 2513 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA] = vector<deUint32>(); 2514 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA] = vector<deUint32>(); 2515 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA] = vector<deUint32>(); 2516 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA] = vector<deUint32>(); 2517 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA] = vector<deUint32>(); 2518 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA] = vector<deUint32>(); 2519 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA] = vector<deUint32>(); 2520 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA] = vector<deUint32>(); 2521 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA] = vector<deUint32>(); 2522 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA] = vector<deUint32>(); 2523 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA] = vector<deUint32>(); 2524 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA] = vector<deUint32>(); 2525 2526 // VIEWCLASS_EAC_R11 2527 compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_R11_EAC); 2528 compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_SIGNED_R11_EAC); 2529 2530 // VIEWCLASS_EAC_RG11 2531 compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_RG11_EAC); 2532 compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_SIGNED_RG11_EAC); 2533 2534 // VIEWCLASS_ETC2_RGB 2535 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_RGB8_ETC2); 2536 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_SRGB8_ETC2); 2537 2538 // VIEWCLASS_ETC2_RGBA 2539 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2); 2540 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); 2541 2542 // VIEWCLASS_ETC2_EAC_RGBA 2543 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); 2544 compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); 2545 2546 // VIEWCLASS_ASTC_4x4_RGBA 2547 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_4x4); 2548 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4); 2549 2550 // VIEWCLASS_ASTC_5x4_RGBA 2551 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x4); 2552 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4); 2553 2554 // VIEWCLASS_ASTC_5x5_RGBA 2555 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x5); 2556 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5); 2557 2558 // VIEWCLASS_ASTC_6x5_RGBA 2559 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x5); 2560 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5); 2561 2562 // VIEWCLASS_ASTC_6x6_RGBA 2563 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x6); 2564 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6); 2565 2566 // VIEWCLASS_ASTC_8x5_RGBA 2567 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x5); 2568 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5); 2569 2570 // VIEWCLASS_ASTC_8x6_RGBA 2571 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x6); 2572 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6); 2573 2574 // VIEWCLASS_ASTC_8x8_RGBA 2575 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x8); 2576 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8); 2577 2578 // VIEWCLASS_ASTC_10x5_RGBA 2579 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x5); 2580 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5); 2581 2582 // VIEWCLASS_ASTC_10x6_RGBA 2583 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x6); 2584 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6); 2585 2586 // VIEWCLASS_ASTC_10x8_RGBA 2587 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x8); 2588 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8); 2589 2590 // VIEWCLASS_ASTC_10x10_RGBA 2591 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x10); 2592 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10); 2593 2594 // VIEWCLASS_ASTC_12x10_RGBA 2595 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x10); 2596 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10); 2597 2598 // VIEWCLASS_ASTC_12x12_RGBA 2599 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x12); 2600 compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12); 2601 2602 // Mixed view classes 2603 mixedViewClasses[VIEWCLASS_128_BITS] = pair<vector<deUint32>, vector<deUint32> >(); 2604 mixedViewClasses[VIEWCLASS_64_BITS] = pair<vector<deUint32>, vector<deUint32> >(); 2605 2606 // 128 bits 2607 2608 // Non compressed 2609 mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32F); 2610 mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32UI); 2611 mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32I); 2612 2613 // Compressed 2614 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); 2615 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); 2616 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RG11_EAC); 2617 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SIGNED_RG11_EAC); 2618 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_4x4); 2619 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x4); 2620 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x5); 2621 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x5); 2622 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x6); 2623 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x5); 2624 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x6); 2625 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x8); 2626 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x5); 2627 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x6); 2628 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x8); 2629 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x10); 2630 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x10); 2631 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x12); 2632 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4); 2633 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4); 2634 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5); 2635 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5); 2636 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6); 2637 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5); 2638 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6); 2639 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8); 2640 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5); 2641 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6); 2642 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8); 2643 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10); 2644 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10); 2645 mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12); 2646 2647 // 64 bits 2648 2649 // Non compressed 2650 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16F); 2651 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16UI); 2652 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16I); 2653 2654 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32F); 2655 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32UI); 2656 mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32I); 2657 2658 // Compressed 2659 mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_R11_EAC); 2660 mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_SIGNED_R11_EAC); 2661 2662 { 2663 TestCaseGroup* const nonCompressedGroup = new TestCaseGroup(m_context, "non_compressed", "Test copying between textures."); 2664 addChild(nonCompressedGroup); 2665 for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = textureFormatViewClasses.begin(); viewClassIter != textureFormatViewClasses.end(); ++viewClassIter) 2666 { 2667 const vector<deUint32>& formats = viewClassIter->second; 2668 const ViewClass viewClass = viewClassIter->first; 2669 TestCaseGroup* const viewGroup = new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass)); 2670 2671 nonCompressedGroup->addChild(viewGroup); 2672 2673 for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++) 2674 for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++) 2675 { 2676 const deUint32 srcFormat = formats[srcFormatNdx]; 2677 const deUint32 dstFormat = formats[dstFormatNdx]; 2678 2679 if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat)) 2680 continue; 2681 2682 addCopyTests(viewGroup, srcFormat, dstFormat); 2683 } 2684 } 2685 } 2686 2687 // ES only 2688 if (!m_isGL45) 2689 { 2690 TestCaseGroup* const compressedGroup = new TestCaseGroup(m_context, "compressed", "Test copying between compressed textures."); 2691 addChild(compressedGroup); 2692 2693 for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = compressedTextureFormatViewClasses.begin(); viewClassIter != compressedTextureFormatViewClasses.end(); ++viewClassIter) 2694 { 2695 const vector<deUint32>& formats = viewClassIter->second; 2696 const ViewClass viewClass = viewClassIter->first; 2697 TestCaseGroup* const viewGroup = new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass)); 2698 2699 compressedGroup->addChild(viewGroup); 2700 2701 for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++) 2702 for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++) 2703 { 2704 const deUint32 srcFormat = formats[srcFormatNdx]; 2705 const deUint32 dstFormat = formats[dstFormatNdx]; 2706 2707 if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat)) 2708 continue; 2709 2710 addCopyTests(viewGroup, srcFormat, dstFormat); 2711 } 2712 } 2713 } 2714 2715 // ES only 2716 if (!m_isGL45) 2717 { 2718 TestCaseGroup* const mixedGroup = new TestCaseGroup(m_context, "mixed", "Test copying between compressed and non-compressed textures."); 2719 addChild(mixedGroup); 2720 2721 2722 for (map<ViewClass, pair<vector<deUint32>, vector<deUint32> > >::const_iterator iter = mixedViewClasses.begin(); iter != mixedViewClasses.end(); ++iter) 2723 { 2724 const ViewClass viewClass = iter->first; 2725 const string viewClassName = string(viewClassToName(viewClass)) + "_mixed"; 2726 TestCaseGroup* const viewGroup = new TestCaseGroup(m_context, viewClassName.c_str(), viewClassName.c_str()); 2727 2728 const vector<deUint32> nonCompressedFormats = iter->second.first; 2729 const vector<deUint32> compressedFormats = iter->second.second; 2730 2731 mixedGroup->addChild(viewGroup); 2732 2733 for (int srcFormatNdx = 0; srcFormatNdx < (int)nonCompressedFormats.size(); srcFormatNdx++) 2734 for (int dstFormatNdx = 0; dstFormatNdx < (int)compressedFormats.size(); dstFormatNdx++) 2735 { 2736 const deUint32 srcFormat = nonCompressedFormats[srcFormatNdx]; 2737 const deUint32 dstFormat = compressedFormats[dstFormatNdx]; 2738 2739 if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat)) 2740 continue; 2741 2742 addCopyTests(viewGroup, srcFormat, dstFormat); 2743 addCopyTests(viewGroup, dstFormat, srcFormat); 2744 } 2745 } 2746 } 2747} 2748 2749} // anonymous 2750 2751TestCaseGroup* createCopyImageTests (Context& context, bool is_GL45) 2752{ 2753 return new CopyImageTests(context, is_GL45); 2754} 2755 2756} // Functional 2757} // gles31 2758} // deqp 2759