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