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