xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fTextureWrapTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 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 Texture wrap mode tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fTextureWrapTests.hpp"
25 #include "glsTextureTestUtil.hpp"
26 #include "gluTexture.hpp"
27 #include "gluStrUtil.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "gluPixelTransfer.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuCompressedTexture.hpp"
33 #include "tcuVectorUtil.hpp"
34 #include "tcuTexLookupVerifier.hpp"
35 #include "deRandom.hpp"
36 #include "deStringUtil.hpp"
37 #include "deMemory.h"
38 
39 #include "glwEnums.hpp"
40 #include "glwFunctions.hpp"
41 
42 namespace deqp
43 {
44 namespace gles3
45 {
46 namespace Functional
47 {
48 
49 using std::string;
50 using std::vector;
51 using tcu::CompressedTexFormat;
52 using tcu::CompressedTexture;
53 using tcu::Sampler;
54 using tcu::TestLog;
55 using namespace glu;
56 using namespace gls::TextureTestUtil;
57 using namespace glu::TextureTestUtil;
58 
59 //! Checks whether any ASTC version (LDR, HDR, full) is supported.
isASTCSupported(const glu::ContextInfo & contextInfo)60 static inline bool isASTCSupported(const glu::ContextInfo &contextInfo)
61 {
62     const vector<string> &extensions = contextInfo.getExtensions();
63 
64     for (int extNdx = 0; extNdx < (int)extensions.size(); extNdx++)
65     {
66         const string &ext = extensions[extNdx];
67 
68         if (ext == "GL_KHR_texture_compression_astc_ldr" || ext == "GL_KHR_texture_compression_astc_hdr" ||
69             ext == "GL_OES_texture_compression_astc")
70             return true;
71     }
72 
73     return false;
74 }
75 
76 enum
77 {
78     VIEWPORT_WIDTH  = 256,
79     VIEWPORT_HEIGHT = 256
80 };
81 
82 class TextureWrapCase : public tcu::TestCase
83 {
84 public:
85     TextureWrapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
86                     const char *name, const char *description, uint32_t format, uint32_t dataType, uint32_t wrapS,
87                     uint32_t wrapT, uint32_t minFilter, uint32_t magFilter, int width, int height,
88                     bool enableRelaxedRef = false);
89     TextureWrapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
90                     const char *name, const char *description, uint32_t wrapS, uint32_t wrapT, uint32_t minFilter,
91                     uint32_t magFilter, const std::vector<std::string> &filenames, bool enableRelaxedRef = false);
92     TextureWrapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
93                     const char *name, const char *description, CompressedTexFormat compressedFormat, uint32_t wrapS,
94                     uint32_t wrapT, uint32_t minFilter, uint32_t magFilter, int width, int height,
95                     bool enableRelaxedRef = false);
96     ~TextureWrapCase(void);
97 
98     void init(void);
99     void deinit(void);
100     IterateResult iterate(void);
101 
102 private:
103     TextureWrapCase(const TextureWrapCase &other);
104     TextureWrapCase &operator=(const TextureWrapCase &other);
105 
106     struct Case
107     {
108         tcu::Vec2 bottomLeft;
109         tcu::Vec2 topRight;
110 
Casedeqp::gles3::Functional::TextureWrapCase::Case111         Case(void)
112         {
113         }
Casedeqp::gles3::Functional::TextureWrapCase::Case114         Case(const tcu::Vec2 &bl, const tcu::Vec2 &tr) : bottomLeft(bl), topRight(tr)
115         {
116         }
117     };
118 
119     glu::RenderContext &m_renderCtx;
120     const glu::ContextInfo &m_renderCtxInfo;
121 
122     const uint32_t m_format;
123     const uint32_t m_dataType;
124     const CompressedTexFormat m_compressedFormat;
125     const uint32_t m_wrapS;
126     const uint32_t m_wrapT;
127     const uint32_t m_minFilter;
128     const uint32_t m_magFilter;
129 
130     int m_width;
131     int m_height;
132     const std::vector<std::string> m_filenames;
133 
134     vector<Case> m_cases;
135     int m_caseNdx;
136 
137     glu::Texture2D *m_texture;
138     TextureRenderer m_renderer;
139 
140     bool m_enableRelaxedRef;
141 };
142 
TextureWrapCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & ctxInfo,const char * name,const char * description,uint32_t format,uint32_t dataType,uint32_t wrapS,uint32_t wrapT,uint32_t minFilter,uint32_t magFilter,int width,int height,bool enableRelaxedRef)143 TextureWrapCase::TextureWrapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
144                                  const glu::ContextInfo &ctxInfo, const char *name, const char *description,
145                                  uint32_t format, uint32_t dataType, uint32_t wrapS, uint32_t wrapT, uint32_t minFilter,
146                                  uint32_t magFilter, int width, int height, bool enableRelaxedRef)
147     : TestCase(testCtx, name, description)
148     , m_renderCtx(renderCtx)
149     , m_renderCtxInfo(ctxInfo)
150     , m_format(format)
151     , m_dataType(dataType)
152     , m_compressedFormat(tcu::COMPRESSEDTEXFORMAT_LAST)
153     , m_wrapS(wrapS)
154     , m_wrapT(wrapT)
155     , m_minFilter(minFilter)
156     , m_magFilter(magFilter)
157     , m_width(width)
158     , m_height(height)
159     , m_caseNdx(0)
160     , m_texture(DE_NULL)
161     , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
162     , m_enableRelaxedRef(enableRelaxedRef)
163 {
164 }
165 
TextureWrapCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & ctxInfo,const char * name,const char * description,uint32_t wrapS,uint32_t wrapT,uint32_t minFilter,uint32_t magFilter,const std::vector<std::string> & filenames,bool enableRelaxedRef)166 TextureWrapCase::TextureWrapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
167                                  const glu::ContextInfo &ctxInfo, const char *name, const char *description,
168                                  uint32_t wrapS, uint32_t wrapT, uint32_t minFilter, uint32_t magFilter,
169                                  const std::vector<std::string> &filenames, bool enableRelaxedRef)
170     : TestCase(testCtx, name, description)
171     , m_renderCtx(renderCtx)
172     , m_renderCtxInfo(ctxInfo)
173     , m_format(GL_NONE)
174     , m_dataType(GL_NONE)
175     , m_compressedFormat(tcu::COMPRESSEDTEXFORMAT_LAST)
176     , m_wrapS(wrapS)
177     , m_wrapT(wrapT)
178     , m_minFilter(minFilter)
179     , m_magFilter(magFilter)
180     , m_width(0)
181     , m_height(0)
182     , m_filenames(filenames)
183     , m_caseNdx(0)
184     , m_texture(DE_NULL)
185     , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
186     , m_enableRelaxedRef(enableRelaxedRef)
187 {
188 }
189 
TextureWrapCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & ctxInfo,const char * name,const char * description,CompressedTexFormat compressedFormat,uint32_t wrapS,uint32_t wrapT,uint32_t minFilter,uint32_t magFilter,int width,int height,bool enableRelaxedRef)190 TextureWrapCase::TextureWrapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
191                                  const glu::ContextInfo &ctxInfo, const char *name, const char *description,
192                                  CompressedTexFormat compressedFormat, uint32_t wrapS, uint32_t wrapT,
193                                  uint32_t minFilter, uint32_t magFilter, int width, int height, bool enableRelaxedRef)
194     : TestCase(testCtx, name, description)
195     , m_renderCtx(renderCtx)
196     , m_renderCtxInfo(ctxInfo)
197     , m_format(GL_NONE)
198     , m_dataType(GL_NONE)
199     , m_compressedFormat(compressedFormat)
200     , m_wrapS(wrapS)
201     , m_wrapT(wrapT)
202     , m_minFilter(minFilter)
203     , m_magFilter(magFilter)
204     , m_width(width)
205     , m_height(height)
206     , m_caseNdx(0)
207     , m_texture(DE_NULL)
208     , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
209     , m_enableRelaxedRef(enableRelaxedRef)
210 {
211 }
212 
~TextureWrapCase(void)213 TextureWrapCase::~TextureWrapCase(void)
214 {
215     deinit();
216 }
217 
init(void)218 void TextureWrapCase::init(void)
219 {
220     // Load or generate texture.
221 
222     if (!m_filenames.empty())
223     {
224         // Load compressed texture from file.
225 
226         DE_ASSERT(m_width == 0 && m_height == 0 && m_format == GL_NONE && m_dataType == GL_NONE);
227 
228         m_texture = glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(),
229                                            (int)m_filenames.size(), m_filenames);
230         m_width   = m_texture->getRefTexture().getWidth();
231         m_height  = m_texture->getRefTexture().getHeight();
232     }
233     else if (m_compressedFormat != tcu::COMPRESSEDTEXFORMAT_LAST)
234     {
235         // Generate compressed texture.
236 
237         DE_ASSERT(m_format == GL_NONE && m_dataType == GL_NONE);
238 
239         if (tcu::isEtcFormat(m_compressedFormat))
240         {
241             // Create ETC texture. Any content is valid.
242 
243             tcu::CompressedTexture compressedTexture(m_compressedFormat, m_width, m_height);
244             const int dataSize  = compressedTexture.getDataSize();
245             uint8_t *const data = (uint8_t *)compressedTexture.getData();
246             de::Random rnd(deStringHash(getName()));
247 
248             for (int i = 0; i < dataSize; i++)
249                 data[i] = rnd.getUint32() & 0xff;
250 
251             m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture);
252         }
253         else if (tcu::isAstcFormat(m_compressedFormat))
254         {
255             // Create ASTC texture by picking from a set of pre-generated blocks.
256 
257             static const int BLOCK_SIZE               = 16;
258             static const uint8_t blocks[][BLOCK_SIZE] = {
259                 // \note All of the following blocks are valid in LDR mode.
260                 {
261                     252,
262                     253,
263                     255,
264                     255,
265                     255,
266                     255,
267                     255,
268                     255,
269                     8,
270                     71,
271                     90,
272                     78,
273                     22,
274                     17,
275                     26,
276                     66,
277                 },
278                 {252, 253, 255, 255, 255, 255, 255, 255, 220, 74, 139, 235, 249, 6, 145, 125},
279                 {252, 253, 255, 255, 255, 255, 255, 255, 223, 251, 28, 206, 54, 251, 160, 174},
280                 {252, 253, 255, 255, 255, 255, 255, 255, 39, 4, 153, 219, 180, 61, 51, 37},
281                 {67, 2, 0, 254, 1, 0, 64, 215, 83, 211, 159, 105, 41, 140, 50, 2},
282                 {67, 130, 0, 170, 84, 255, 65, 215, 83, 211, 159, 105, 41, 140, 50, 2},
283                 {67, 2, 129, 38, 51, 229, 95, 215, 83, 211, 159, 105, 41, 140, 50, 2},
284                 {67, 130, 193, 56, 213, 144, 95, 215, 83, 211, 159, 105, 41, 140, 50, 2}};
285 
286             if (!isASTCSupported(
287                     m_renderCtxInfo)) // \note Any level of ASTC support is enough, since we're only using LDR blocks.
288                 throw tcu::NotSupportedError("ASTC not supported");
289 
290             tcu::CompressedTexture compressedTexture(m_compressedFormat, m_width, m_height);
291             const int dataSize  = compressedTexture.getDataSize();
292             uint8_t *const data = (uint8_t *)compressedTexture.getData();
293             de::Random rnd(deStringHash(getName()));
294             DE_ASSERT(dataSize % BLOCK_SIZE == 0);
295 
296             for (int i = 0; i < dataSize / BLOCK_SIZE; i++)
297                 deMemcpy(&data[i * BLOCK_SIZE], &blocks[rnd.getInt(0, DE_LENGTH_OF_ARRAY(blocks) - 1)][0], BLOCK_SIZE);
298 
299             // \note All blocks are valid LDR blocks so ASTCMODE_* doesn't change anything
300             m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture,
301                                            tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
302         }
303         else
304             DE_ASSERT(false);
305     }
306     else
307     {
308         m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
309 
310         // Fill level 0.
311         m_texture->getRefTexture().allocLevel(0);
312         if (m_wrapS == GL_REPEAT || m_wrapT == GL_REPEAT)
313         {
314             // If run in repeat mode, use conical style texture to avoid edge sample result have a huge difference when coordinate offset in allow range.
315             tcu::fillWithComponentGradients3(m_texture->getRefTexture().getLevel(0),
316                                              tcu::Vec4(-0.5f, -0.5f, -0.5f, 1.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
317         }
318         else
319         {
320             tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0),
321                                             tcu::Vec4(-0.5f, -0.5f, -0.5f, 1.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
322         }
323 
324         m_texture->upload();
325     }
326 
327     // Sub-cases.
328 
329     m_cases.push_back(Case(tcu::Vec2(-1.5f, -3.0f), tcu::Vec2(1.5f, 2.5f)));
330     m_cases.push_back(Case(tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f)));
331     DE_ASSERT(m_caseNdx == 0);
332 
333     // Initialize to success, set to failure later if needed.
334 
335     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
336 }
337 
deinit(void)338 void TextureWrapCase::deinit(void)
339 {
340     delete m_texture;
341     m_texture = DE_NULL;
342 
343     m_renderer.clear();
344 }
345 
iterate(void)346 TextureWrapCase::IterateResult TextureWrapCase::iterate(void)
347 {
348     const glw::Functions &gl = m_renderCtx.getFunctions();
349     TestLog &log             = m_testCtx.getLog();
350     const RandomViewport viewport(m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT,
351                                   deStringHash(getName()) + m_caseNdx);
352     tcu::Surface renderedFrame(viewport.width, viewport.height);
353     ReferenceParams refParams(TEXTURETYPE_2D);
354     const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat();
355     vector<float> texCoord;
356     const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat);
357     // \note For non-sRGB ASTC formats, the values are fp16 in range [0..1], not the range assumed given by tcu::getTextureFormatInfo().
358     const bool useDefaultColorScaleAndBias =
359         !tcu::isAstcFormat(m_compressedFormat) || tcu::isAstcSRGBFormat(m_compressedFormat);
360 
361     // Bind to unit 0.
362     gl.activeTexture(GL_TEXTURE0);
363     gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
364 
365     // Setup filtering and wrap modes.
366     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
367     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
368     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
369     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter);
370 
371     GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
372 
373     // Parameters for reference images.
374     refParams.sampler     = mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
375     refParams.lodMode     = LODMODE_EXACT;
376     refParams.samplerType = getSamplerType(m_texture->getRefTexture().getFormat());
377     refParams.colorScale  = useDefaultColorScaleAndBias ? texFormatInfo.lookupScale : tcu::Vec4(1.0f);
378     refParams.colorBias   = useDefaultColorScaleAndBias ? texFormatInfo.lookupBias : tcu::Vec4(0.0f);
379 
380     gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
381     computeQuadTexCoord2D(texCoord, m_cases[m_caseNdx].bottomLeft, m_cases[m_caseNdx].topRight);
382     m_renderer.renderQuad(0, &texCoord[0], refParams);
383     glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
384 
385     {
386         const tcu::ScopedLogSection section(log, string("Test") + de::toString(m_caseNdx),
387                                             string("Test ") + de::toString(m_caseNdx));
388         const bool isNearestOnly           = m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
389         const bool isSRGB                  = tcu::isSRGB(texFormat);
390         const tcu::PixelFormat pixelFormat = m_renderCtx.getRenderTarget().getPixelFormat();
391         const tcu::IVec4 colorBits =
392             tcu::max(getBitsVec(pixelFormat) - (isNearestOnly && !isSRGB ? 1 : 2), tcu::IVec4(0));
393         tcu::LodPrecision lodPrecision;
394         tcu::LookupPrecision lookupPrecision;
395 
396         lodPrecision.derivateBits = 18;
397         lodPrecision.lodBits      = 5;
398         lookupPrecision.colorThreshold =
399             tcu::computeColorBitsThreshold(getBitsVec(pixelFormat), colorBits) / refParams.colorScale;
400         lookupPrecision.coordBits = tcu::IVec3(20, 20, 0);
401         lookupPrecision.uvwBits   = tcu::IVec3(5, 5, 0);
402         lookupPrecision.colorMask = getCompareMask(pixelFormat);
403 
404         log << TestLog::Message << "Note: lookup coordinates: bottom-left " << m_cases[m_caseNdx].bottomLeft
405             << ", top-right " << m_cases[m_caseNdx].topRight << TestLog::EndMessage;
406 
407         bool isOk = verifyTextureResult(m_testCtx, renderedFrame.getAccess(), m_texture->getRefTexture(), &texCoord[0],
408                                         refParams, lookupPrecision, lodPrecision, pixelFormat);
409 
410         if ((isOk == false) && m_enableRelaxedRef && m_renderer.getTexCoordPrecision() != PRECISION_HIGHP)
411         {
412             refParams.float16TexCoord = true;
413             isOk |= verifyTextureResult(m_testCtx, renderedFrame.getAccess(), m_texture->getRefTexture(), &texCoord[0],
414                                         refParams, lookupPrecision, lodPrecision, pixelFormat);
415         }
416 
417         if (!isOk)
418             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
419     }
420 
421     m_caseNdx++;
422     return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
423 }
424 
TextureWrapTests(Context & context)425 TextureWrapTests::TextureWrapTests(Context &context) : TestCaseGroup(context, "wrap", "Wrap Mode Tests")
426 {
427 }
428 
~TextureWrapTests(void)429 TextureWrapTests::~TextureWrapTests(void)
430 {
431 }
432 
init(void)433 void TextureWrapTests::init(void)
434 {
435     static const struct
436     {
437         const char *name;
438         uint32_t mode;
439     } wrapModes[] = {{"clamp", GL_CLAMP_TO_EDGE}, {"repeat", GL_REPEAT}, {"mirror", GL_MIRRORED_REPEAT}};
440 
441     static const struct
442     {
443         const char *name;
444         uint32_t mode;
445     } filteringModes[] = {{"nearest", GL_NEAREST}, {"linear", GL_LINEAR}};
446 
447 #define FOR_EACH(ITERATOR, ARRAY, BODY)                                      \
448     for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++) \
449     BODY
450 
451     // RGBA8 cases.
452     {
453         static const struct
454         {
455             const char *name;
456             int width;
457             int height;
458         } rgba8Sizes[] = {{"pot", 64, 128}, {"npot", 63, 112}};
459 
460         {
461             TestCaseGroup *const rgba8Group = new TestCaseGroup(m_context, "rgba8", "");
462             addChild(rgba8Group);
463 
464             FOR_EACH(size, rgba8Sizes,
465                      FOR_EACH(wrapS, wrapModes,
466                               FOR_EACH(wrapT, wrapModes, FOR_EACH(filter, filteringModes, {
467                                            const string name =
468                                                string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" +
469                                                filteringModes[filter].name + "_" + rgba8Sizes[size].name;
470                                            rgba8Group->addChild(new TextureWrapCase(
471                                                m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
472                                                name.c_str(), "", GL_RGBA, GL_UNSIGNED_BYTE, wrapModes[wrapS].mode,
473                                                wrapModes[wrapT].mode, filteringModes[filter].mode,
474                                                filteringModes[filter].mode, rgba8Sizes[size].width,
475                                                rgba8Sizes[size].height));
476                                        }))))
477         }
478     }
479 
480     // ETC1 cases.
481     {
482         TestCaseGroup *const etc1Group = new TestCaseGroup(m_context, "etc1", "");
483         addChild(etc1Group);
484 
485         // Power-of-two ETC1 texture
486         std::vector<std::string> potFilenames;
487         potFilenames.push_back("data/etc1/photo_helsinki_mip_0.pkm");
488 
489         FOR_EACH(wrapS, wrapModes,
490                  FOR_EACH(wrapT, wrapModes, FOR_EACH(filter, filteringModes, {
491                               const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name +
492                                                   "_" + filteringModes[filter].name + "_pot";
493 
494                               bool enableRelaxedPrecisionRef = wrapModes[wrapS].mode == GL_REPEAT ||
495                                                                wrapModes[wrapT].mode == GL_REPEAT ||
496                                                                wrapModes[wrapS].mode == GL_MIRRORED_REPEAT ||
497                                                                wrapModes[wrapT].mode == GL_MIRRORED_REPEAT;
498 
499                               etc1Group->addChild(new TextureWrapCase(
500                                   m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
501                                   wrapModes[wrapS].mode, wrapModes[wrapT].mode, filteringModes[filter].mode,
502                                   filteringModes[filter].mode, potFilenames, enableRelaxedPrecisionRef));
503                           })))
504 
505         std::vector<std::string> npotFilenames;
506         npotFilenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
507 
508         // NPOT ETC1 texture
509         FOR_EACH(wrapS, wrapModes,
510                  FOR_EACH(wrapT, wrapModes, FOR_EACH(filter, filteringModes, {
511                               const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name +
512                                                   "_" + filteringModes[filter].name + "_npot";
513 
514                               bool enableRelaxedPrecisionRef = wrapModes[wrapS].mode == GL_REPEAT ||
515                                                                wrapModes[wrapT].mode == GL_REPEAT ||
516                                                                wrapModes[wrapS].mode == GL_MIRRORED_REPEAT ||
517                                                                wrapModes[wrapT].mode == GL_MIRRORED_REPEAT;
518 
519                               etc1Group->addChild(new TextureWrapCase(
520                                   m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
521                                   wrapModes[wrapS].mode, wrapModes[wrapT].mode, filteringModes[filter].mode,
522                                   filteringModes[filter].mode, npotFilenames, enableRelaxedPrecisionRef));
523                           })))
524     }
525 
526     // ETC-2 (and EAC) cases.
527     {
528         static const struct
529         {
530             const char *name;
531             CompressedTexFormat format;
532         } etc2Formats[] = {{
533                                "eac_r11",
534                                tcu::COMPRESSEDTEXFORMAT_EAC_R11,
535                            },
536                            {
537                                "eac_signed_r11",
538                                tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11,
539                            },
540                            {
541                                "eac_rg11",
542                                tcu::COMPRESSEDTEXFORMAT_EAC_RG11,
543                            },
544                            {
545                                "eac_signed_rg11",
546                                tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11,
547                            },
548                            {
549                                "etc2_rgb8",
550                                tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8,
551                            },
552                            {
553                                "etc2_srgb8",
554                                tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8,
555                            },
556                            {
557                                "etc2_rgb8_punchthrough_alpha1",
558                                tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,
559                            },
560                            {
561                                "etc2_srgb8_punchthrough_alpha1",
562                                tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,
563                            },
564                            {
565                                "etc2_eac_rgba8",
566                                tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8,
567                            },
568                            {
569                                "etc2_eac_srgb8_alpha8",
570                                tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8,
571                            }};
572 
573         static const struct
574         {
575             const char *name;
576             int width;
577             int height;
578         } etc2Sizes[] = {{"pot", 64, 128}, {"npot", 123, 107}};
579 
580         for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(etc2Formats); formatNdx++)
581         {
582             TestCaseGroup *const formatGroup = new TestCaseGroup(m_context, etc2Formats[formatNdx].name, "");
583             addChild(formatGroup);
584 
585             FOR_EACH(size, etc2Sizes,
586                      FOR_EACH(wrapS, wrapModes,
587                               FOR_EACH(wrapT, wrapModes, FOR_EACH(filter, filteringModes, {
588                                            const string name = string("") + wrapModes[wrapS].name + "_" +
589                                                                wrapModes[wrapT].name + "_" +
590                                                                filteringModes[filter].name + "_" + etc2Sizes[size].name;
591 
592                                            bool enableRelaxedPrecisionRef =
593                                                wrapModes[wrapS].mode == GL_REPEAT ||
594                                                wrapModes[wrapT].mode == GL_REPEAT ||
595                                                wrapModes[wrapS].mode == GL_MIRRORED_REPEAT ||
596                                                wrapModes[wrapT].mode == GL_MIRRORED_REPEAT;
597 
598                                            formatGroup->addChild(new TextureWrapCase(
599                                                m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
600                                                name.c_str(), "", etc2Formats[formatNdx].format, wrapModes[wrapS].mode,
601                                                wrapModes[wrapT].mode, filteringModes[filter].mode,
602                                                filteringModes[filter].mode, etc2Sizes[size].width,
603                                                etc2Sizes[size].height, enableRelaxedPrecisionRef));
604                                        }))))
605         }
606     }
607 
608     // ASTC cases.
609     {
610         for (int formatI = 0; formatI < tcu::COMPRESSEDTEXFORMAT_LAST; formatI++)
611         {
612             const CompressedTexFormat format = (CompressedTexFormat)formatI;
613 
614             if (!tcu::isAstcFormat(format))
615                 continue;
616 
617             {
618                 const tcu::IVec3 blockSize = tcu::getBlockPixelSize(format);
619                 const string formatName    = "astc_" + de::toString(blockSize.x()) + "x" + de::toString(blockSize.y()) +
620                                           (tcu::isAstcSRGBFormat(format) ? "_srgb" : "");
621                 TestCaseGroup *const formatGroup = new TestCaseGroup(m_context, formatName.c_str(), "");
622                 addChild(formatGroup);
623 
624                 DE_ASSERT(blockSize.z() == 1);
625 
626                 // \note This array is NOT static.
627                 const struct
628                 {
629                     const char *name;
630                     int width;
631                     int height;
632                 } formatSizes[] = {
633                     {"divisible", blockSize.x() * 10, blockSize.y() * 10},
634                     {"not_divisible", blockSize.x() * 10 + 1, blockSize.y() * 10 + 1},
635                 };
636 
637                 FOR_EACH(size, formatSizes,
638                          FOR_EACH(wrapS, wrapModes,
639                                   FOR_EACH(wrapT, wrapModes, FOR_EACH(filter, filteringModes, {
640                                                string name = string("") + wrapModes[wrapS].name + "_" +
641                                                              wrapModes[wrapT].name + "_" + filteringModes[filter].name +
642                                                              "_" + formatSizes[size].name;
643 
644                                                bool enableRelaxedPrecisionRef =
645                                                    wrapModes[wrapS].mode == GL_REPEAT ||
646                                                    wrapModes[wrapT].mode == GL_REPEAT ||
647                                                    wrapModes[wrapS].mode == GL_MIRRORED_REPEAT ||
648                                                    wrapModes[wrapT].mode == GL_MIRRORED_REPEAT;
649 
650                                                formatGroup->addChild(new TextureWrapCase(
651                                                    m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
652                                                    name.c_str(), "", format, wrapModes[wrapS].mode,
653                                                    wrapModes[wrapT].mode, filteringModes[filter].mode,
654                                                    filteringModes[filter].mode, formatSizes[size].width,
655                                                    formatSizes[size].height, enableRelaxedPrecisionRef));
656                                            }))))
657             }
658         }
659     }
660 }
661 
662 } // namespace Functional
663 } // namespace gles3
664 } // namespace deqp
665