1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 format tests.
22 *
23 * Constants:
24 * + nearest-neighbor filtering
25 * + no mipmaps
26 * + full texture coordinate range (but not outside) tested
27 * + accessed from fragment shader
28 * + texture unit 0
29 * + named texture object
30 *
31 * Variables:
32 * + texture format
33 * + texture type: 2D or cubemap
34 *//*--------------------------------------------------------------------*/
35
36 #include "es2fTextureFormatTests.hpp"
37 #include "glsTextureTestUtil.hpp"
38 #include "gluTexture.hpp"
39 #include "gluStrUtil.hpp"
40 #include "gluTextureUtil.hpp"
41 #include "gluPixelTransfer.hpp"
42 #include "tcuSurfaceAccess.hpp"
43 #include "tcuTestLog.hpp"
44 #include "tcuTextureUtil.hpp"
45
46 #include "deStringUtil.hpp"
47
48 #include "glwEnums.hpp"
49 #include "glwFunctions.hpp"
50
51 namespace deqp
52 {
53 namespace gles2
54 {
55 namespace Functional
56 {
57
58 using std::string;
59 using std::vector;
60 using tcu::Sampler;
61 using tcu::TestLog;
62 using namespace glu;
63 using namespace gls::TextureTestUtil;
64 using namespace glu::TextureTestUtil;
65
66 // Texture2DFormatCase
67
68 class Texture2DFormatCase : public tcu::TestCase
69 {
70 public:
71 Texture2DFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
72 const char *description, uint32_t format, uint32_t dataType, int width, int height);
73 ~Texture2DFormatCase(void);
74
75 void init(void);
76 void deinit(void);
77 IterateResult iterate(void);
78
79 private:
80 Texture2DFormatCase(const Texture2DFormatCase &other);
81 Texture2DFormatCase &operator=(const Texture2DFormatCase &other);
82
83 glu::RenderContext &m_renderCtx;
84
85 const uint32_t m_format;
86 const uint32_t m_dataType;
87 const int m_width;
88 const int m_height;
89
90 glu::Texture2D *m_texture;
91 TextureRenderer m_renderer;
92 };
93
Texture2DFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,uint32_t format,uint32_t dataType,int width,int height)94 Texture2DFormatCase::Texture2DFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
95 const char *description, uint32_t format, uint32_t dataType, int width,
96 int height)
97 : TestCase(testCtx, name, description)
98 , m_renderCtx(renderCtx)
99 , m_format(format)
100 , m_dataType(dataType)
101 , m_width(width)
102 , m_height(height)
103 , m_texture(DE_NULL)
104 , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
105 {
106 }
107
~Texture2DFormatCase(void)108 Texture2DFormatCase::~Texture2DFormatCase(void)
109 {
110 deinit();
111 }
112
init(void)113 void Texture2DFormatCase::init(void)
114 {
115 TestLog &log = m_testCtx.getLog();
116 tcu::TextureFormat fmt = glu::mapGLTransferFormat(m_format, m_dataType);
117 tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(fmt);
118 std::ostringstream fmtName;
119
120 fmtName << getTextureFormatStr(m_format) << ", " << getTypeStr(m_dataType);
121
122 log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
123 << ",\n fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient" << TestLog::EndMessage;
124
125 m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
126
127 // Fill level 0.
128 m_texture->getRefTexture().allocLevel(0);
129 tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
130 }
131
deinit(void)132 void Texture2DFormatCase::deinit(void)
133 {
134 delete m_texture;
135 m_texture = DE_NULL;
136
137 m_renderer.clear();
138 }
139
iterate(void)140 Texture2DFormatCase::IterateResult Texture2DFormatCase::iterate(void)
141 {
142 TestLog &log = m_testCtx.getLog();
143 const glw::Functions &gl = m_renderCtx.getFunctions();
144 RandomViewport viewport(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
145 tcu::Surface renderedFrame(viewport.width, viewport.height);
146 tcu::Surface referenceFrame(viewport.width, viewport.height);
147 tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
148 vector<float> texCoord;
149 ReferenceParams renderParams(TEXTURETYPE_2D);
150 tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
151 const uint32_t wrapS = GL_CLAMP_TO_EDGE;
152 const uint32_t wrapT = GL_CLAMP_TO_EDGE;
153 const uint32_t minFilter = GL_NEAREST;
154 const uint32_t magFilter = GL_NEAREST;
155
156 renderParams.flags |= RenderParams::LOG_ALL;
157 renderParams.samplerType = getSamplerType(m_texture->getRefTexture().getFormat());
158 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE,
159 Sampler::NEAREST, Sampler::NEAREST);
160 renderParams.colorScale = spec.lookupScale;
161 renderParams.colorBias = spec.lookupBias;
162
163 computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
164
165 log << TestLog::Message << "Texture parameters:"
166 << "\n WRAP_S = " << getTextureParameterValueStr(GL_TEXTURE_WRAP_S, wrapS)
167 << "\n WRAP_T = " << getTextureParameterValueStr(GL_TEXTURE_WRAP_T, wrapT)
168 << "\n MIN_FILTER = " << getTextureParameterValueStr(GL_TEXTURE_MIN_FILTER, minFilter)
169 << "\n MAG_FILTER = " << getTextureParameterValueStr(GL_TEXTURE_MAG_FILTER, magFilter) << TestLog::EndMessage;
170
171 // Setup base viewport.
172 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
173
174 // Upload texture data to GL.
175 m_texture->upload();
176
177 // Bind to unit 0.
178 gl.activeTexture(GL_TEXTURE0);
179 gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
180
181 // Setup nearest neighbor filtering and clamp-to-edge.
182 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
183 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
184 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
185 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
186
187 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
188
189 // Draw.
190 m_renderer.renderQuad(0, &texCoord[0], renderParams);
191 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
192 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
193
194 // Compute reference.
195 sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()),
196 m_texture->getRefTexture(), &texCoord[0], renderParams);
197
198 // Compare and log.
199 bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
200
201 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
202 isOk ? "Pass" : "Image comparison failed");
203
204 return STOP;
205 }
206
207 // TextureCubeFormatCase
208
209 class TextureCubeFormatCase : public tcu::TestCase
210 {
211 public:
212 TextureCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
213 const char *description, uint32_t format, uint32_t dataType, int width, int height);
214 ~TextureCubeFormatCase(void);
215
216 void init(void);
217 void deinit(void);
218 IterateResult iterate(void);
219
220 private:
221 TextureCubeFormatCase(const TextureCubeFormatCase &other);
222 TextureCubeFormatCase &operator=(const TextureCubeFormatCase &other);
223
224 bool testFace(tcu::CubeFace face);
225
226 glu::RenderContext &m_renderCtx;
227
228 const uint32_t m_format;
229 const uint32_t m_dataType;
230 const int m_width;
231 const int m_height;
232
233 glu::TextureCube *m_texture;
234 TextureRenderer m_renderer;
235
236 int m_curFace;
237 bool m_isOk;
238 };
239
TextureCubeFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,uint32_t format,uint32_t dataType,int width,int height)240 TextureCubeFormatCase::TextureCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
241 const char *description, uint32_t format, uint32_t dataType, int width,
242 int height)
243 : TestCase(testCtx, name, description)
244 , m_renderCtx(renderCtx)
245 , m_format(format)
246 , m_dataType(dataType)
247 , m_width(width)
248 , m_height(height)
249 , m_texture(DE_NULL)
250 , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
251 , m_curFace(0)
252 , m_isOk(false)
253 {
254 }
255
~TextureCubeFormatCase(void)256 TextureCubeFormatCase::~TextureCubeFormatCase(void)
257 {
258 deinit();
259 }
260
init(void)261 void TextureCubeFormatCase::init(void)
262 {
263 TestLog &log = m_testCtx.getLog();
264 tcu::TextureFormat fmt = glu::mapGLTransferFormat(m_format, m_dataType);
265 tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(fmt);
266 std::ostringstream fmtName;
267
268 if (m_dataType)
269 fmtName << getTextureFormatStr(m_format) << ", " << getTypeStr(m_dataType);
270 else
271 fmtName << getTextureFormatStr(m_format);
272
273 log << TestLog::Message << "Cube map texture, " << fmtName.str() << ", " << m_width << "x" << m_height
274 << ",\n fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient" << TestLog::EndMessage;
275
276 DE_ASSERT(m_width == m_height);
277 m_texture = m_dataType != GL_NONE ?
278 new TextureCube(m_renderCtx, m_format, m_dataType, m_width) // Implicit internal format.
279 :
280 new TextureCube(m_renderCtx, m_format, m_width); // Explicit internal format.
281
282 // Fill level 0.
283 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
284 {
285 tcu::Vec4 gMin, gMax;
286
287 switch (face)
288 {
289 case 0:
290 gMin = spec.valueMin.swizzle(0, 1, 2, 3);
291 gMax = spec.valueMax.swizzle(0, 1, 2, 3);
292 break;
293 case 1:
294 gMin = spec.valueMin.swizzle(2, 1, 0, 3);
295 gMax = spec.valueMax.swizzle(2, 1, 0, 3);
296 break;
297 case 2:
298 gMin = spec.valueMin.swizzle(1, 2, 0, 3);
299 gMax = spec.valueMax.swizzle(1, 2, 0, 3);
300 break;
301 case 3:
302 gMin = spec.valueMax.swizzle(0, 1, 2, 3);
303 gMax = spec.valueMin.swizzle(0, 1, 2, 3);
304 break;
305 case 4:
306 gMin = spec.valueMax.swizzle(2, 1, 0, 3);
307 gMax = spec.valueMin.swizzle(2, 1, 0, 3);
308 break;
309 case 5:
310 gMin = spec.valueMax.swizzle(1, 2, 0, 3);
311 gMax = spec.valueMin.swizzle(1, 2, 0, 3);
312 break;
313 default:
314 DE_ASSERT(false);
315 }
316
317 m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
318 tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), gMin, gMax);
319 }
320
321 // Upload texture data to GL.
322 m_texture->upload();
323
324 // Initialize iteration state.
325 m_curFace = 0;
326 m_isOk = true;
327 }
328
deinit(void)329 void TextureCubeFormatCase::deinit(void)
330 {
331 delete m_texture;
332 m_texture = DE_NULL;
333
334 m_renderer.clear();
335 }
336
testFace(tcu::CubeFace face)337 bool TextureCubeFormatCase::testFace(tcu::CubeFace face)
338 {
339 const glw::Functions &gl = m_renderCtx.getFunctions();
340 TestLog &log = m_testCtx.getLog();
341 RandomViewport viewport(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()) + (uint32_t)face);
342 tcu::Surface renderedFrame(viewport.width, viewport.height);
343 tcu::Surface referenceFrame(viewport.width, viewport.height);
344 tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
345 vector<float> texCoord;
346 ReferenceParams renderParams(TEXTURETYPE_CUBE);
347 tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
348
349 renderParams.samplerType = getSamplerType(m_texture->getRefTexture().getFormat());
350 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE,
351 Sampler::NEAREST, Sampler::NEAREST);
352 renderParams.sampler.seamlessCubeMap = false;
353 renderParams.colorScale = spec.lookupScale;
354 renderParams.colorBias = spec.lookupBias;
355
356 // Log render info on first face.
357 if (face == tcu::CUBEFACE_NEGATIVE_X)
358 renderParams.flags |= RenderParams::LOG_ALL;
359
360 computeQuadTexCoordCube(texCoord, face);
361
362 // \todo [2011-10-28 pyry] Image set name / section?
363 log << TestLog::Message << face << TestLog::EndMessage;
364
365 // Setup base viewport.
366 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
367
368 // Bind to unit 0.
369 gl.activeTexture(GL_TEXTURE0);
370 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
371
372 // Setup nearest neighbor filtering and clamp-to-edge.
373 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
374 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
375 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
376 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
377
378 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
379
380 m_renderer.renderQuad(0, &texCoord[0], renderParams);
381 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
382 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
383
384 // Compute reference.
385 sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()),
386 m_texture->getRefTexture(), &texCoord[0], renderParams);
387
388 // Compare and log.
389 return compareImages(log, referenceFrame, renderedFrame, threshold);
390 }
391
iterate(void)392 TextureCubeFormatCase::IterateResult TextureCubeFormatCase::iterate(void)
393 {
394 // Execute test for all faces.
395 if (!testFace((tcu::CubeFace)m_curFace))
396 m_isOk = false;
397
398 m_curFace += 1;
399
400 if (m_curFace == tcu::CUBEFACE_LAST)
401 {
402 m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
403 m_isOk ? "Pass" : "Image comparison failed");
404 return STOP;
405 }
406 else
407 return CONTINUE;
408 }
409
TextureFormatTests(Context & context)410 TextureFormatTests::TextureFormatTests(Context &context) : TestCaseGroup(context, "format", "Texture Format Tests")
411 {
412 }
413
~TextureFormatTests(void)414 TextureFormatTests::~TextureFormatTests(void)
415 {
416 }
417
418 // Compressed2DFormatCase
419
420 class Compressed2DFormatCase : public tcu::TestCase
421 {
422 public:
423 Compressed2DFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
424 const glu::ContextInfo &renderCtxInfo, const char *name, const char *description,
425 const std::vector<std::string> &filenames);
426 ~Compressed2DFormatCase(void);
427
428 void init(void);
429 void deinit(void);
430 IterateResult iterate(void);
431
432 private:
433 Compressed2DFormatCase(const Compressed2DFormatCase &other);
434 Compressed2DFormatCase &operator=(const Compressed2DFormatCase &other);
435
436 glu::RenderContext &m_renderCtx;
437 const glu::ContextInfo &m_renderCtxInfo;
438
439 std::vector<std::string> m_filenames;
440
441 glu::Texture2D *m_texture;
442 TextureRenderer m_renderer;
443 };
444
Compressed2DFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & renderCtxInfo,const char * name,const char * description,const std::vector<std::string> & filenames)445 Compressed2DFormatCase::Compressed2DFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
446 const glu::ContextInfo &renderCtxInfo, const char *name,
447 const char *description, const std::vector<std::string> &filenames)
448 : TestCase(testCtx, name, description)
449 , m_renderCtx(renderCtx)
450 , m_renderCtxInfo(renderCtxInfo)
451 , m_filenames(filenames)
452 , m_texture(DE_NULL)
453 , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
454 {
455 }
456
~Compressed2DFormatCase(void)457 Compressed2DFormatCase::~Compressed2DFormatCase(void)
458 {
459 deinit();
460 }
461
init(void)462 void Compressed2DFormatCase::init(void)
463 {
464 // Create texture.
465 m_texture =
466 Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
467 }
468
deinit(void)469 void Compressed2DFormatCase::deinit(void)
470 {
471 delete m_texture;
472 m_texture = DE_NULL;
473
474 m_renderer.clear();
475 }
476
iterate(void)477 Compressed2DFormatCase::IterateResult Compressed2DFormatCase::iterate(void)
478 {
479 const glw::Functions &gl = m_renderCtx.getFunctions();
480 TestLog &log = m_testCtx.getLog();
481 RandomViewport viewport(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getWidth(),
482 m_texture->getRefTexture().getHeight(), deStringHash(getName()));
483 tcu::Surface renderedFrame(viewport.width, viewport.height);
484 tcu::Surface referenceFrame(viewport.width, viewport.height);
485 tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
486 vector<float> texCoord;
487
488 computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
489
490 // Setup base viewport.
491 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
492
493 // Bind to unit 0.
494 gl.activeTexture(GL_TEXTURE0);
495 gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
496
497 // Setup nearest neighbor filtering and clamp-to-edge.
498 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
499 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
500 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
501 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
502
503 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
504
505 // Draw.
506 m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D);
507 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
508 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
509
510 // Compute reference.
511 ReferenceParams refParams(TEXTURETYPE_2D);
512 refParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE,
513 Sampler::NEAREST, Sampler::NEAREST);
514 sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()),
515 m_texture->getRefTexture(), &texCoord[0], refParams);
516
517 // Compare and log.
518 bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
519
520 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
521 isOk ? "Pass" : "Image comparison failed");
522
523 return STOP;
524 }
525
526 // CompressedCubeFormatCase
527
528 class CompressedCubeFormatCase : public tcu::TestCase
529 {
530 public:
531 CompressedCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
532 const glu::ContextInfo &renderCtxInfo, const char *name, const char *description,
533 const std::vector<std::string> &filenames);
534 ~CompressedCubeFormatCase(void);
535
536 void init(void);
537 void deinit(void);
538 IterateResult iterate(void);
539
540 private:
541 CompressedCubeFormatCase(const CompressedCubeFormatCase &other);
542 CompressedCubeFormatCase &operator=(const CompressedCubeFormatCase &other);
543
544 bool testFace(tcu::CubeFace face);
545
546 glu::RenderContext &m_renderCtx;
547 const glu::ContextInfo &m_renderCtxInfo;
548
549 std::vector<std::string> m_filenames;
550
551 glu::TextureCube *m_texture;
552 TextureRenderer m_renderer;
553
554 int m_curFace;
555 bool m_isOk;
556 };
557
CompressedCubeFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & renderCtxInfo,const char * name,const char * description,const std::vector<std::string> & filenames)558 CompressedCubeFormatCase::CompressedCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
559 const glu::ContextInfo &renderCtxInfo, const char *name,
560 const char *description, const std::vector<std::string> &filenames)
561 : TestCase(testCtx, name, description)
562 , m_renderCtx(renderCtx)
563 , m_renderCtxInfo(renderCtxInfo)
564 , m_filenames(filenames)
565 , m_texture(DE_NULL)
566 , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
567 , m_curFace(0)
568 , m_isOk(false)
569 {
570 }
571
~CompressedCubeFormatCase(void)572 CompressedCubeFormatCase::~CompressedCubeFormatCase(void)
573 {
574 deinit();
575 }
576
init(void)577 void CompressedCubeFormatCase::init(void)
578 {
579 // Create texture.
580 DE_ASSERT(m_filenames.size() % 6 == 0);
581 m_texture = TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6,
582 m_filenames);
583
584 m_curFace = 0;
585 m_isOk = true;
586 }
587
deinit(void)588 void CompressedCubeFormatCase::deinit(void)
589 {
590 delete m_texture;
591 m_texture = DE_NULL;
592
593 m_renderer.clear();
594 }
595
testFace(tcu::CubeFace face)596 bool CompressedCubeFormatCase::testFace(tcu::CubeFace face)
597 {
598 const glw::Functions &gl = m_renderCtx.getFunctions();
599 TestLog &log = m_testCtx.getLog();
600 RandomViewport viewport(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getSize(),
601 m_texture->getRefTexture().getSize(), deStringHash(getName()) + (uint32_t)face);
602 tcu::Surface renderedFrame(viewport.width, viewport.height);
603 tcu::Surface referenceFrame(viewport.width, viewport.height);
604 Sampler sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST,
605 Sampler::NEAREST);
606 tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
607 vector<float> texCoord;
608
609 computeQuadTexCoordCube(texCoord, face);
610
611 // \todo [2011-10-28 pyry] Image set name / section?
612 log << TestLog::Message << face << TestLog::EndMessage;
613
614 // Setup base viewport.
615 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
616
617 // Bind to unit 0.
618 gl.activeTexture(GL_TEXTURE0);
619 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
620
621 // Setup nearest neighbor filtering and clamp-to-edge.
622 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
623 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
624 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
625 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
626
627 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
628
629 m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE);
630 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
631 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
632
633 // Compute reference.
634 sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()),
635 m_texture->getRefTexture(), &texCoord[0], ReferenceParams(TEXTURETYPE_CUBE, sampler));
636
637 // Compare and log.
638 return compareImages(log, referenceFrame, renderedFrame, threshold);
639 }
640
iterate(void)641 CompressedCubeFormatCase::IterateResult CompressedCubeFormatCase::iterate(void)
642 {
643 // Execute test for all faces.
644 if (!testFace((tcu::CubeFace)m_curFace))
645 m_isOk = false;
646
647 m_curFace += 1;
648
649 if (m_curFace == tcu::CUBEFACE_LAST)
650 {
651 m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
652 m_isOk ? "Pass" : "Image comparison failed");
653 return STOP;
654 }
655 else
656 return CONTINUE;
657 }
658
toStringVector(const char * const * str,int numStr)659 vector<string> toStringVector(const char *const *str, int numStr)
660 {
661 vector<string> v;
662 v.resize(numStr);
663 for (int i = 0; i < numStr; i++)
664 v[i] = str[i];
665 return v;
666 }
667
init(void)668 void TextureFormatTests::init(void)
669 {
670 struct
671 {
672 const char *name;
673 uint32_t format;
674 uint32_t dataType;
675 } texFormats[] = {{"a8", GL_ALPHA, GL_UNSIGNED_BYTE},
676 {"l8", GL_LUMINANCE, GL_UNSIGNED_BYTE},
677 {"la88", GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE},
678 {"rgb565", GL_RGB, GL_UNSIGNED_SHORT_5_6_5},
679 {"rgb888", GL_RGB, GL_UNSIGNED_BYTE},
680 {"rgba4444", GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4},
681 {"rgba5551", GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1},
682 {"rgba8888", GL_RGBA, GL_UNSIGNED_BYTE}};
683
684 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
685 {
686 uint32_t format = texFormats[formatNdx].format;
687 uint32_t dataType = texFormats[formatNdx].dataType;
688 string nameBase = texFormats[formatNdx].name;
689 string descriptionBase = string(glu::getTextureFormatName(format)) + ", " + glu::getTypeName(dataType);
690
691 addChild(new Texture2DFormatCase(m_testCtx, m_context.getRenderContext(), (nameBase + "_2d_pot").c_str(),
692 (descriptionBase + ", GL_TEXTURE_2D").c_str(), format, dataType, 128, 128));
693 addChild(new Texture2DFormatCase(m_testCtx, m_context.getRenderContext(), (nameBase + "_2d_npot").c_str(),
694 (descriptionBase + ", GL_TEXTURE_2D").c_str(), format, dataType, 63, 112));
695 addChild(new TextureCubeFormatCase(m_testCtx, m_context.getRenderContext(), (nameBase + "_cube_pot").c_str(),
696 (descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(), format, dataType, 64,
697 64));
698 addChild(new TextureCubeFormatCase(m_testCtx, m_context.getRenderContext(), (nameBase + "_cube_npot").c_str(),
699 (descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(), format, dataType, 57,
700 57));
701 }
702
703 // ETC-1 compressed formats.
704 {
705 static const char *filenames[] = {"data/etc1/photo_helsinki_mip_0.pkm", "data/etc1/photo_helsinki_mip_1.pkm",
706 "data/etc1/photo_helsinki_mip_2.pkm", "data/etc1/photo_helsinki_mip_3.pkm",
707 "data/etc1/photo_helsinki_mip_4.pkm", "data/etc1/photo_helsinki_mip_5.pkm",
708 "data/etc1/photo_helsinki_mip_6.pkm", "data/etc1/photo_helsinki_mip_7.pkm"};
709 addChild(new Compressed2DFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
710 "etc1_2d_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D",
711 toStringVector(filenames, DE_LENGTH_OF_ARRAY(filenames))));
712 }
713
714 {
715 vector<string> filenames;
716 filenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
717 addChild(new Compressed2DFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
718 "etc1_2d_npot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", filenames));
719 }
720
721 {
722 static const char *faceExt[] = {"neg_x", "pos_x", "neg_y", "pos_y", "neg_z", "pos_z"};
723
724 const int potNumLevels = 7;
725 vector<string> potFilenames;
726 for (int level = 0; level < potNumLevels; level++)
727 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
728 potFilenames.push_back(string("data/etc1/skybox_") + faceExt[face] + "_mip_" + de::toString(level) +
729 ".pkm");
730
731 addChild(new CompressedCubeFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
732 "etc1_cube_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_CUBE_MAP", potFilenames));
733
734 vector<string> npotFilenames;
735 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
736 npotFilenames.push_back(string("data/etc1/skybox_61x61_") + faceExt[face] + ".pkm");
737
738 addChild(new CompressedCubeFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
739 "etc1_cube_npot", "GL_ETC_RGB8_OES, GL_TEXTURE_CUBE_MAP", npotFilenames));
740 }
741 }
742
743 } // namespace Functional
744 } // namespace gles2
745 } // namespace deqp
746