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