xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fTextureFormatTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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