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