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