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