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 Mipmapping accuracy tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3aTextureMipmapTests.hpp"
25
26 #include "glsTextureTestUtil.hpp"
27 #include "gluTexture.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "gluPixelTransfer.hpp"
30 #include "tcuTextureUtil.hpp"
31 #include "tcuMatrix.hpp"
32 #include "tcuMatrixUtil.hpp"
33 #include "deStringUtil.hpp"
34 #include "deRandom.hpp"
35 #include "deString.h"
36
37 #include "glwFunctions.hpp"
38 #include "glwEnums.hpp"
39
40 namespace deqp
41 {
42 namespace gles3
43 {
44 namespace Accuracy
45 {
46
47 using std::string;
48 using std::vector;
49 using tcu::TestLog;
50 using tcu::Vec2;
51 using tcu::Vec3;
52 using tcu::Vec4;
53 using tcu::IVec4;
54 using namespace gls::TextureTestUtil;
55 using namespace glu::TextureTestUtil;
56
57
58 enum CoordType
59 {
60 COORDTYPE_BASIC, //!< texCoord = translateScale(position).
61 COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values.
62 COORDTYPE_AFFINE, //!< texCoord = translateScaleRotateShear(position).
63 COORDTYPE_PROJECTED, //!< Projected coordinates, w != 1
64
65 COORDTYPE_LAST
66 };
67
68 // Texture2DMipmapCase
69
70 class Texture2DMipmapCase : public tcu::TestCase
71 {
72 public:
73
74 Texture2DMipmapCase (tcu::TestContext& testCtx,
75 glu::RenderContext& renderCtx,
76 const glu::ContextInfo& renderCtxInfo,
77 const char* name,
78 const char* desc,
79 CoordType coordType,
80 deUint32 minFilter,
81 deUint32 wrapS,
82 deUint32 wrapT,
83 deUint32 format,
84 deUint32 dataType,
85 int width,
86 int height);
87 ~Texture2DMipmapCase (void);
88
89 void init (void);
90 void deinit (void);
91 IterateResult iterate (void);
92
93 private:
94 Texture2DMipmapCase (const Texture2DMipmapCase& other);
95 Texture2DMipmapCase& operator= (const Texture2DMipmapCase& other);
96
97 glu::RenderContext& m_renderCtx;
98 const glu::ContextInfo& m_renderCtxInfo;
99
100 CoordType m_coordType;
101 deUint32 m_minFilter;
102 deUint32 m_wrapS;
103 deUint32 m_wrapT;
104 deUint32 m_format;
105 deUint32 m_dataType;
106 int m_width;
107 int m_height;
108
109 glu::Texture2D* m_texture;
110 TextureRenderer m_renderer;
111 };
112
Texture2DMipmapCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & renderCtxInfo,const char * name,const char * desc,CoordType coordType,deUint32 minFilter,deUint32 wrapS,deUint32 wrapT,deUint32 format,deUint32 dataType,int width,int height)113 Texture2DMipmapCase::Texture2DMipmapCase (tcu::TestContext& testCtx,
114 glu::RenderContext& renderCtx,
115 const glu::ContextInfo& renderCtxInfo,
116 const char* name,
117 const char* desc,
118 CoordType coordType,
119 deUint32 minFilter,
120 deUint32 wrapS,
121 deUint32 wrapT,
122 deUint32 format,
123 deUint32 dataType,
124 int width,
125 int height)
126 : TestCase (testCtx, tcu::NODETYPE_ACCURACY, name, desc)
127 , m_renderCtx (renderCtx)
128 , m_renderCtxInfo (renderCtxInfo)
129 , m_coordType (coordType)
130 , m_minFilter (minFilter)
131 , m_wrapS (wrapS)
132 , m_wrapT (wrapT)
133 , m_format (format)
134 , m_dataType (dataType)
135 , m_width (width)
136 , m_height (height)
137 , m_texture (DE_NULL)
138 , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
139 {
140 }
141
~Texture2DMipmapCase(void)142 Texture2DMipmapCase::~Texture2DMipmapCase (void)
143 {
144 deinit();
145 }
146
init(void)147 void Texture2DMipmapCase::init (void)
148 {
149 m_texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
150
151 int numLevels = deLog2Floor32(de::max(m_width, m_height))+1;
152
153 // Fill texture with colored grid.
154 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
155 {
156 deUint32 step = 0xff / (numLevels-1);
157 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
158 deUint32 dec = 0xff - inc;
159 deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
160 deUint32 color = 0xff000000 | rgb;
161
162 m_texture->getRefTexture().allocLevel(levelNdx);
163 tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec());
164 }
165 }
166
deinit(void)167 void Texture2DMipmapCase::deinit (void)
168 {
169 delete m_texture;
170 m_texture = DE_NULL;
171
172 m_renderer.clear();
173 }
174
getBasicTexCoord2D(std::vector<float> & dst,int cellNdx)175 static void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx)
176 {
177 static const struct
178 {
179 Vec2 bottomLeft;
180 Vec2 topRight;
181 } s_basicCoords[] =
182 {
183 { Vec2(-0.1f, 0.1f), Vec2( 0.8f, 1.0f) },
184 { Vec2(-0.3f, -0.6f), Vec2( 0.7f, 0.4f) },
185 { Vec2(-0.3f, 0.6f), Vec2( 0.7f, -0.9f) },
186 { Vec2(-0.8f, 0.6f), Vec2( 0.7f, -0.9f) },
187
188 { Vec2(-0.5f, -0.5f), Vec2( 1.5f, 1.5f) },
189 { Vec2( 1.0f, -1.0f), Vec2(-1.3f, 1.0f) },
190 { Vec2( 1.2f, -1.0f), Vec2(-1.3f, 1.6f) },
191 { Vec2( 2.2f, -1.1f), Vec2(-1.3f, 0.8f) },
192
193 { Vec2(-1.5f, 1.6f), Vec2( 1.7f, -1.4f) },
194 { Vec2( 2.0f, 1.6f), Vec2( 2.3f, -1.4f) },
195 { Vec2( 1.3f, -2.6f), Vec2(-2.7f, 2.9f) },
196 { Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) },
197
198 { Vec2( -8.0f, 9.0f), Vec2( 8.3f, -7.0f) },
199 { Vec2(-16.0f, 10.0f), Vec2( 18.3f, 24.0f) },
200 { Vec2( 30.2f, 55.0f), Vec2(-24.3f, -1.6f) },
201 { Vec2(-33.2f, 64.1f), Vec2( 32.1f, -64.1f) },
202 };
203
204 DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));
205
206 const Vec2& bottomLeft = s_basicCoords[cellNdx].bottomLeft;
207 const Vec2& topRight = s_basicCoords[cellNdx].topRight;
208
209 computeQuadTexCoord2D(dst, bottomLeft, topRight);
210 }
211
getAffineTexCoord2D(std::vector<float> & dst,int cellNdx)212 static void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx)
213 {
214 // Use basic coords as base.
215 getBasicTexCoord2D(dst, cellNdx);
216
217 // Rotate based on cell index.
218 float angle = 2.0f*DE_PI * ((float)cellNdx / 16.0f);
219 tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle);
220
221 // Second and third row are sheared.
222 float shearX = de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f;
223 tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));
224
225 tcu::Mat2 transform = rotMatrix * shearMatrix;
226 Vec2 p0 = transform * Vec2(dst[0], dst[1]);
227 Vec2 p1 = transform * Vec2(dst[2], dst[3]);
228 Vec2 p2 = transform * Vec2(dst[4], dst[5]);
229 Vec2 p3 = transform * Vec2(dst[6], dst[7]);
230
231 dst[0] = p0.x(); dst[1] = p0.y();
232 dst[2] = p1.x(); dst[3] = p1.y();
233 dst[4] = p2.x(); dst[5] = p2.y();
234 dst[6] = p3.x(); dst[7] = p3.y();
235 }
236
iterate(void)237 Texture2DMipmapCase::IterateResult Texture2DMipmapCase::iterate (void)
238 {
239 // Constants.
240 const deUint32 magFilter = GL_NEAREST;
241
242 const glw::Functions& gl = m_renderCtx.getFunctions();
243 TestLog& log = m_testCtx.getLog();
244
245 const tcu::Texture2D& refTexture = m_texture->getRefTexture();
246 const tcu::TextureFormat& texFmt = refTexture.getFormat();
247 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
248
249 int texWidth = refTexture.getWidth();
250 int texHeight = refTexture.getHeight();
251 int defViewportWidth = texWidth*4;
252 int defViewportHeight = texHeight*4;
253
254 RandomViewport viewport (m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
255 ReferenceParams sampleParams (TEXTURETYPE_2D);
256 vector<float> texCoord;
257
258 bool isProjected = m_coordType == COORDTYPE_PROJECTED;
259 bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS;
260
261 tcu::Surface renderedFrame (viewport.width, viewport.height);
262
263 // Accuracy cases test against ideal lod computation.
264 tcu::Surface idealFrame (viewport.width, viewport.height);
265
266 // Viewport is divided into 4x4 grid.
267 int gridWidth = 4;
268 int gridHeight = 4;
269 int cellWidth = viewport.width / gridWidth;
270 int cellHeight = viewport.height / gridHeight;
271
272 // Accuracy measurements are off unless we get the expected viewport size.
273 if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
274 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
275
276 // Sampling parameters.
277 sampleParams.sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
278 sampleParams.samplerType = glu::TextureTestUtil::getSamplerType(m_texture->getRefTexture().getFormat());
279 sampleParams.colorBias = fmtInfo.lookupBias;
280 sampleParams.colorScale = fmtInfo.lookupScale;
281 sampleParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
282
283 // Upload texture data.
284 m_texture->upload();
285
286 // Use unit 0.
287 gl.activeTexture(GL_TEXTURE0);
288
289 // Bind gradient texture and setup sampler parameters.
290 gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
291 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
292 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
293 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
294 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
295
296 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
297
298 // Bias values.
299 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
300
301 // Projection values.
302 static const Vec4 s_projections[] =
303 {
304 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
305 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
306 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
307 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
308 };
309
310 // Render cells.
311 for (int gridY = 0; gridY < gridHeight; gridY++)
312 {
313 for (int gridX = 0; gridX < gridWidth; gridX++)
314 {
315 int curX = cellWidth*gridX;
316 int curY = cellHeight*gridY;
317 int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
318 int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
319 int cellNdx = gridY*gridWidth + gridX;
320
321 // Compute texcoord.
322 switch (m_coordType)
323 {
324 case COORDTYPE_BASIC_BIAS: // Fall-through.
325 case COORDTYPE_PROJECTED:
326 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
327 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
328 default: DE_ASSERT(DE_FALSE);
329 }
330
331 if (isProjected)
332 sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
333
334 if (useLodBias)
335 sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
336
337 // Render with GL.
338 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
339 m_renderer.renderQuad(0, &texCoord[0], sampleParams);
340
341 // Render reference(s).
342 {
343 tcu::SurfaceAccess idealDst(idealFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY, curW, curH);
344 sampleParams.lodMode = LODMODE_EXACT;
345 sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], sampleParams);
346 }
347 }
348 }
349
350 // Read result.
351 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
352
353 // Compare and log.
354 {
355 const int bestScoreDiff = (texWidth/16)*(texHeight/16);
356 const int worstScoreDiff = texWidth*texHeight;
357
358 int score = measureAccuracy(log, idealFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
359 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
360 }
361
362 return STOP;
363 }
364
365 // TextureCubeMipmapCase
366
367 class TextureCubeMipmapCase : public tcu::TestCase
368 {
369 public:
370
371 TextureCubeMipmapCase (tcu::TestContext& testCtx,
372 glu::RenderContext& renderCtx,
373 const glu::ContextInfo& renderCtxInfo,
374 const char* name,
375 const char* desc,
376 CoordType coordType,
377 deUint32 minFilter,
378 deUint32 wrapS,
379 deUint32 wrapT,
380 deUint32 format,
381 deUint32 dataType,
382 int size);
383 ~TextureCubeMipmapCase (void);
384
385 void init (void);
386 void deinit (void);
387 IterateResult iterate (void);
388
389 private:
390 TextureCubeMipmapCase (const TextureCubeMipmapCase& other);
391 TextureCubeMipmapCase& operator= (const TextureCubeMipmapCase& other);
392
393 glu::RenderContext& m_renderCtx;
394 const glu::ContextInfo& m_renderCtxInfo;
395
396 CoordType m_coordType;
397 deUint32 m_minFilter;
398 deUint32 m_wrapS;
399 deUint32 m_wrapT;
400 deUint32 m_format;
401 deUint32 m_dataType;
402 int m_size;
403
404 glu::TextureCube* m_texture;
405 TextureRenderer m_renderer;
406 };
407
TextureCubeMipmapCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & renderCtxInfo,const char * name,const char * desc,CoordType coordType,deUint32 minFilter,deUint32 wrapS,deUint32 wrapT,deUint32 format,deUint32 dataType,int size)408 TextureCubeMipmapCase::TextureCubeMipmapCase (tcu::TestContext& testCtx,
409 glu::RenderContext& renderCtx,
410 const glu::ContextInfo& renderCtxInfo,
411 const char* name,
412 const char* desc,
413 CoordType coordType,
414 deUint32 minFilter,
415 deUint32 wrapS,
416 deUint32 wrapT,
417 deUint32 format,
418 deUint32 dataType,
419 int size)
420 : TestCase (testCtx, tcu::NODETYPE_ACCURACY, name, desc)
421 , m_renderCtx (renderCtx)
422 , m_renderCtxInfo (renderCtxInfo)
423 , m_coordType (coordType)
424 , m_minFilter (minFilter)
425 , m_wrapS (wrapS)
426 , m_wrapT (wrapT)
427 , m_format (format)
428 , m_dataType (dataType)
429 , m_size (size)
430 , m_texture (DE_NULL)
431 , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
432 {
433 }
434
~TextureCubeMipmapCase(void)435 TextureCubeMipmapCase::~TextureCubeMipmapCase (void)
436 {
437 deinit();
438 }
439
init(void)440 void TextureCubeMipmapCase::init (void)
441 {
442 m_texture = new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_size);
443
444 int numLevels = deLog2Floor32(m_size)+1;
445
446 // Fill texture with colored grid.
447 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
448 {
449 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
450 {
451 deUint32 step = 0xff / (numLevels-1);
452 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
453 deUint32 dec = 0xff - inc;
454 deUint32 rgb = 0;
455
456 switch (faceNdx)
457 {
458 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
459 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
460 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
461 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
462 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
463 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
464 }
465
466 deUint32 color = 0xff000000 | rgb;
467
468 m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx);
469 tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
470 }
471 }
472 }
473
deinit(void)474 void TextureCubeMipmapCase::deinit (void)
475 {
476 delete m_texture;
477 m_texture = DE_NULL;
478
479 m_renderer.clear();
480 }
481
randomPartition(vector<IVec4> & dst,de::Random & rnd,int x,int y,int width,int height)482 static void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height)
483 {
484 const int minWidth = 8;
485 const int minHeight = 8;
486
487 bool partition = rnd.getFloat() > 0.4f;
488 bool partitionX = partition && width > minWidth && rnd.getBool();
489 bool partitionY = partition && height > minHeight && !partitionX;
490
491 if (partitionX)
492 {
493 int split = width/2 + rnd.getInt(-width/4, +width/4);
494 randomPartition(dst, rnd, x, y, split, height);
495 randomPartition(dst, rnd, x+split, y, width-split, height);
496 }
497 else if (partitionY)
498 {
499 int split = height/2 + rnd.getInt(-height/4, +height/4);
500 randomPartition(dst, rnd, x, y, width, split);
501 randomPartition(dst, rnd, x, y+split, width, height-split);
502 }
503 else
504 dst.push_back(IVec4(x, y, width, height));
505 }
506
computeGridLayout(vector<IVec4> & dst,int width,int height)507 static void computeGridLayout (vector<IVec4>& dst, int width, int height)
508 {
509 de::Random rnd(7);
510 randomPartition(dst, rnd, 0, 0, width, height);
511 }
512
iterate(void)513 TextureCubeMipmapCase::IterateResult TextureCubeMipmapCase::iterate (void)
514 {
515 // Constants.
516 const deUint32 magFilter = GL_NEAREST;
517
518 int texWidth = m_texture->getRefTexture().getSize();
519 int texHeight = m_texture->getRefTexture().getSize();
520
521 int defViewportWidth = texWidth*2;
522 int defViewportHeight = texHeight*2;
523
524 const glw::Functions& gl = m_renderCtx.getFunctions();
525 TestLog& log = m_testCtx.getLog();
526 RandomViewport viewport (m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
527 tcu::Sampler sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
528 sampler.seamlessCubeMap = true;
529
530 vector<float> texCoord;
531
532 bool isProjected = m_coordType == COORDTYPE_PROJECTED;
533 bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS;
534
535 tcu::Surface renderedFrame (viewport.width, viewport.height);
536
537 // Accuracy cases test against ideal lod computation.
538 tcu::Surface idealFrame (viewport.width, viewport.height);
539
540 // Accuracy measurements are off unless we get the expected viewport size.
541 if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
542 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
543
544 // Upload texture data.
545 m_texture->upload();
546
547 // Use unit 0.
548 gl.activeTexture(GL_TEXTURE0);
549
550 // Bind gradient texture and setup sampler parameters.
551 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
552 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS);
553 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT);
554 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter);
555 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter);
556
557 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
558
559 // Compute grid.
560 vector<IVec4> gridLayout;
561 computeGridLayout(gridLayout, viewport.width, viewport.height);
562
563 // Bias values.
564 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
565
566 // Projection values \note Less agressive than in 2D case due to smaller quads.
567 static const Vec4 s_projections[] =
568 {
569 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
570 Vec4(1.3f, 0.8f, 0.6f, 1.1f),
571 Vec4(0.8f, 1.0f, 1.2f, 0.8f),
572 Vec4(1.2f, 1.0f, 1.3f, 0.9f)
573 };
574
575 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
576 {
577 int curX = gridLayout[cellNdx].x();
578 int curY = gridLayout[cellNdx].y();
579 int curW = gridLayout[cellNdx].z();
580 int curH = gridLayout[cellNdx].w();
581 tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
582 ReferenceParams params (TEXTURETYPE_CUBE);
583
584 params.sampler = sampler;
585
586 DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported.
587 computeQuadTexCoordCube(texCoord, cubeFace);
588
589 if (isProjected)
590 {
591 params.flags |= ReferenceParams::PROJECTED;
592 params.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
593 }
594
595 if (useLodBias)
596 {
597 params.flags |= ReferenceParams::USE_BIAS;
598 params.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
599 }
600
601 // Render with GL.
602 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
603 m_renderer.renderQuad(0, &texCoord[0], params);
604
605 // Render reference(s).
606 {
607 tcu::SurfaceAccess idealDst(idealFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY, curW, curH);
608 params.lodMode = LODMODE_EXACT;
609 sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params);
610 }
611 }
612
613 // Read result.
614 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
615
616 // Compare and log.
617 {
618 const int bestScoreDiff = (texWidth/16)*(texHeight/16);
619 const int worstScoreDiff = texWidth*texHeight;
620
621 int score = measureAccuracy(log, idealFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
622 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
623 }
624
625 return STOP;
626 }
627
TextureMipmapTests(Context & context)628 TextureMipmapTests::TextureMipmapTests (Context& context)
629 : TestCaseGroup(context, "mipmap", "Mipmapping accuracy tests")
630 {
631 }
632
~TextureMipmapTests(void)633 TextureMipmapTests::~TextureMipmapTests (void)
634 {
635 }
636
init(void)637 void TextureMipmapTests::init (void)
638 {
639 tcu::TestCaseGroup* group2D = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Mipmapping");
640 tcu::TestCaseGroup* groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cube Map Filtering");
641 addChild(group2D);
642 addChild(groupCube);
643
644 static const struct
645 {
646 const char* name;
647 deUint32 mode;
648 } wrapModes[] =
649 {
650 { "clamp", GL_CLAMP_TO_EDGE },
651 { "repeat", GL_REPEAT },
652 { "mirror", GL_MIRRORED_REPEAT }
653 };
654
655 static const struct
656 {
657 const char* name;
658 deUint32 mode;
659 } minFilterModes[] =
660 {
661 { "nearest_nearest", GL_NEAREST_MIPMAP_NEAREST },
662 { "linear_nearest", GL_LINEAR_MIPMAP_NEAREST },
663 { "nearest_linear", GL_NEAREST_MIPMAP_LINEAR },
664 { "linear_linear", GL_LINEAR_MIPMAP_LINEAR }
665 };
666
667 static const struct
668 {
669 CoordType type;
670 const char* name;
671 const char* desc;
672 } coordTypes[] =
673 {
674 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
675 { COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform" },
676 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }
677 };
678
679 const int tex2DWidth = 64;
680 const int tex2DHeight = 64;
681
682 // 2D cases.
683 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
684 {
685 tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc);
686 group2D->addChild(coordTypeGroup);
687
688 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
689 {
690 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
691 {
692 std::ostringstream name;
693 name << minFilterModes[minFilter].name
694 << "_" << wrapModes[wrapMode].name;
695
696 coordTypeGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
697 name.str().c_str(), "",
698 coordTypes[coordType].type,
699 minFilterModes[minFilter].mode,
700 wrapModes[wrapMode].mode,
701 wrapModes[wrapMode].mode,
702 GL_RGBA, GL_UNSIGNED_BYTE,
703 tex2DWidth, tex2DHeight));
704 }
705 }
706 }
707
708 const int cubeMapSize = 64;
709
710 static const struct
711 {
712 CoordType type;
713 const char* name;
714 const char* desc;
715 } cubeCoordTypes[] =
716 {
717 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
718 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }
719 };
720
721 // Cubemap cases.
722 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
723 {
724 tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc);
725 groupCube->addChild(coordTypeGroup);
726
727 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
728 {
729 coordTypeGroup->addChild(new TextureCubeMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
730 minFilterModes[minFilter].name, "",
731 cubeCoordTypes[coordType].type,
732 minFilterModes[minFilter].mode,
733 GL_CLAMP_TO_EDGE,
734 GL_CLAMP_TO_EDGE,
735 GL_RGBA, GL_UNSIGNED_BYTE, cubeMapSize));
736 }
737 }
738 }
739
740 } // Accuracy
741 } // gles3
742 } // deqp
743