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