1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Mipmapping tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es3fTextureMipmapTests.hpp"
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 "tcuTexLookupVerifier.hpp"
34 #include "tcuVectorUtil.hpp"
35 #include "deStringUtil.hpp"
36 #include "deRandom.hpp"
38 #include "glwFunctions.hpp"
39 #include "glwEnums.hpp"
43 using namespace deqp::gls;
59 using namespace gls::TextureTestUtil;
60 using namespace glu::TextureTestUtil;
62 static float getMinLodForCell (int cellNdx)
64 static const float s_values[] =
83 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
86 static float getMaxLodForCell (int cellNdx)
88 static const float s_values[] =
108 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
113 COORDTYPE_BASIC, //!< texCoord = translateScale(position).
114 COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values.
115 COORDTYPE_AFFINE, //!< texCoord = translateScaleRotateShear(position).
116 COORDTYPE_PROJECTED, //!< Projected coordinates, w != 1
121 // Texture2DMipmapCase
123 class Texture2DMipmapCase : public tcu::TestCase
127 Texture2DMipmapCase (tcu::TestContext& testCtx,
128 glu::RenderContext& renderCtx,
129 const glu::ContextInfo& renderCtxInfo,
140 ~Texture2DMipmapCase (void);
144 IterateResult iterate (void);
147 Texture2DMipmapCase (const Texture2DMipmapCase& other);
148 Texture2DMipmapCase& operator= (const Texture2DMipmapCase& other);
150 glu::RenderContext& m_renderCtx;
151 const glu::ContextInfo& m_renderCtxInfo;
153 CoordType m_coordType;
154 deUint32 m_minFilter;
162 glu::Texture2D* m_texture;
163 TextureRenderer m_renderer;
166 Texture2DMipmapCase::Texture2DMipmapCase (tcu::TestContext& testCtx,
167 glu::RenderContext& renderCtx,
168 const glu::ContextInfo& renderCtxInfo,
179 : TestCase (testCtx, name, desc)
180 , m_renderCtx (renderCtx)
181 , m_renderCtxInfo (renderCtxInfo)
182 , m_coordType (coordType)
183 , m_minFilter (minFilter)
187 , m_dataType (dataType)
190 , m_texture (DE_NULL)
191 , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
195 Texture2DMipmapCase::~Texture2DMipmapCase (void)
200 void Texture2DMipmapCase::init (void)
202 if (m_coordType == COORDTYPE_PROJECTED && m_renderCtx.getRenderTarget().getNumSamples() > 0)
203 throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config");
205 m_texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
207 int numLevels = deLog2Floor32(de::max(m_width, m_height))+1;
209 // Fill texture with colored grid.
210 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
212 deUint32 step = 0xff / (numLevels-1);
213 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
214 deUint32 dec = 0xff - inc;
215 deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
216 deUint32 color = 0xff000000 | rgb;
218 m_texture->getRefTexture().allocLevel(levelNdx);
219 tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec());
223 void Texture2DMipmapCase::deinit (void)
231 static void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx)
239 { Vec2(-0.1f, 0.1f), Vec2( 0.8f, 1.0f) },
240 { Vec2(-0.3f, -0.6f), Vec2( 0.7f, 0.4f) },
241 { Vec2(-0.3f, 0.6f), Vec2( 0.7f, -0.9f) },
242 { Vec2(-0.8f, 0.6f), Vec2( 0.7f, -0.9f) },
244 { Vec2(-0.5f, -0.5f), Vec2( 1.5f, 1.5f) },
245 { Vec2( 1.0f, -1.0f), Vec2(-1.3f, 1.0f) },
246 { Vec2( 1.2f, -1.0f), Vec2(-1.3f, 1.6f) },
247 { Vec2( 2.2f, -1.1f), Vec2(-1.3f, 0.8f) },
249 { Vec2(-1.5f, 1.6f), Vec2( 1.7f, -1.4f) },
250 { Vec2( 2.0f, 1.6f), Vec2( 2.3f, -1.4f) },
251 { Vec2( 1.3f, -2.6f), Vec2(-2.7f, 2.9f) },
252 { Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) },
254 { Vec2( -8.0f, 9.0f), Vec2( 8.3f, -7.0f) },
255 { Vec2(-16.0f, 10.0f), Vec2( 18.3f, 24.0f) },
256 { Vec2( 30.2f, 55.0f), Vec2(-24.3f, -1.6f) },
257 { Vec2(-33.2f, 64.1f), Vec2( 32.1f, -64.1f) },
260 DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));
262 const Vec2& bottomLeft = s_basicCoords[cellNdx].bottomLeft;
263 const Vec2& topRight = s_basicCoords[cellNdx].topRight;
265 computeQuadTexCoord2D(dst, bottomLeft, topRight);
268 static void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx)
270 // Use basic coords as base.
271 getBasicTexCoord2D(dst, cellNdx);
273 // Rotate based on cell index.
274 float angle = 2.0f*DE_PI * ((float)cellNdx / 16.0f);
275 tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle);
277 // Second and third row are sheared.
278 float shearX = de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f;
279 tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));
281 tcu::Mat2 transform = rotMatrix * shearMatrix;
282 Vec2 p0 = transform * Vec2(dst[0], dst[1]);
283 Vec2 p1 = transform * Vec2(dst[2], dst[3]);
284 Vec2 p2 = transform * Vec2(dst[4], dst[5]);
285 Vec2 p3 = transform * Vec2(dst[6], dst[7]);
287 dst[0] = p0.x(); dst[1] = p0.y();
288 dst[2] = p1.x(); dst[3] = p1.y();
289 dst[4] = p2.x(); dst[5] = p2.y();
290 dst[6] = p3.x(); dst[7] = p3.y();
293 Texture2DMipmapCase::IterateResult Texture2DMipmapCase::iterate (void)
295 const glw::Functions& gl = m_renderCtx.getFunctions();
297 const tcu::Texture2D& refTexture = m_texture->getRefTexture();
299 const deUint32 magFilter = GL_NEAREST;
300 const int texWidth = refTexture.getWidth();
301 const int texHeight = refTexture.getHeight();
302 const int defViewportWidth = texWidth*4;
303 const int defViewportHeight = texHeight*4;
305 const RandomViewport viewport (m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
306 ReferenceParams sampleParams (TEXTURETYPE_2D);
307 vector<float> texCoord;
309 const bool isProjected = m_coordType == COORDTYPE_PROJECTED;
310 const bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS;
312 tcu::Surface renderedFrame (viewport.width, viewport.height);
314 // Viewport is divided into 4x4 grid.
317 int cellWidth = viewport.width / gridWidth;
318 int cellHeight = viewport.height / gridHeight;
320 // Bail out if rendertarget is too small.
321 if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2)
322 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
324 // Sampling parameters.
325 sampleParams.sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
326 sampleParams.samplerType = glu::TextureTestUtil::getSamplerType(m_texture->getRefTexture().getFormat());
327 sampleParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
328 sampleParams.lodMode = LODMODE_EXACT; // Use ideal lod.
330 // Upload texture data.
333 // Bind gradient texture and setup sampler parameters.
334 gl.bindTexture (GL_TEXTURE_2D, m_texture->getGLTexture());
335 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
336 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
337 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
338 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
340 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
343 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
345 // Projection values.
346 static const Vec4 s_projections[] =
348 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
349 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
350 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
351 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
355 for (int gridY = 0; gridY < gridHeight; gridY++)
357 for (int gridX = 0; gridX < gridWidth; gridX++)
359 const int curX = cellWidth*gridX;
360 const int curY = cellHeight*gridY;
361 const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
362 const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
363 const int cellNdx = gridY*gridWidth + gridX;
368 case COORDTYPE_BASIC_BIAS: // Fall-through.
369 case COORDTYPE_PROJECTED:
370 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
371 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
372 default: DE_ASSERT(DE_FALSE);
376 sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
379 sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
382 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
383 m_renderer.renderQuad(0, &texCoord[0], sampleParams);
388 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
392 const tcu::PixelFormat& pixelFormat = m_renderCtx.getRenderTarget().getPixelFormat();
393 const bool isTrilinear = m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
394 tcu::Surface referenceFrame (viewport.width, viewport.height);
395 tcu::Surface errorMask (viewport.width, viewport.height);
396 tcu::LookupPrecision lookupPrec;
397 tcu::LodPrecision lodPrec (tcu::LodPrecision::RULE_OPENGL);
398 int numFailedPixels = 0;
400 lookupPrec.coordBits = tcu::IVec3(20, 20, 0);
401 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
402 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
403 lookupPrec.colorMask = getCompareMask(pixelFormat);
404 lodPrec.derivateBits = 10;
405 lodPrec.lodBits = isProjected ? 6 : 8;
407 for (int gridY = 0; gridY < gridHeight; gridY++)
409 for (int gridX = 0; gridX < gridWidth; gridX++)
411 const int curX = cellWidth*gridX;
412 const int curY = cellHeight*gridY;
413 const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
414 const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
415 const int cellNdx = gridY*gridWidth + gridX;
420 case COORDTYPE_BASIC_BIAS: // Fall-through.
421 case COORDTYPE_PROJECTED:
422 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
423 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
424 default: DE_ASSERT(DE_FALSE);
428 sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
431 sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
433 // Render ideal result
434 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
435 refTexture, &texCoord[0], sampleParams);
438 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
439 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
440 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
441 m_texture->getRefTexture(), &texCoord[0], sampleParams,
442 lookupPrec, lodPrec, m_testCtx.getWatchDog());
446 if (numFailedPixels > 0)
447 m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
449 m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
450 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
452 if (numFailedPixels > 0)
454 m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
455 << TestLog::Image("ErrorMask", "Error mask", errorMask);
458 m_testCtx.getLog() << TestLog::EndImageSet;
461 const bool isOk = numFailedPixels == 0;
462 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
463 isOk ? "Pass" : "Image verification failed");
470 // TextureCubeMipmapCase
472 class TextureCubeMipmapCase : public tcu::TestCase
476 TextureCubeMipmapCase (tcu::TestContext& testCtx,
477 glu::RenderContext& renderCtx,
478 const glu::ContextInfo& renderCtxInfo,
488 ~TextureCubeMipmapCase (void);
492 IterateResult iterate (void);
495 TextureCubeMipmapCase (const TextureCubeMipmapCase& other);
496 TextureCubeMipmapCase& operator= (const TextureCubeMipmapCase& other);
498 glu::RenderContext& m_renderCtx;
499 const glu::ContextInfo& m_renderCtxInfo;
501 CoordType m_coordType;
502 deUint32 m_minFilter;
509 glu::TextureCube* m_texture;
510 TextureRenderer m_renderer;
513 TextureCubeMipmapCase::TextureCubeMipmapCase (tcu::TestContext& testCtx,
514 glu::RenderContext& renderCtx,
515 const glu::ContextInfo& renderCtxInfo,
525 : TestCase (testCtx, name, desc)
526 , m_renderCtx (renderCtx)
527 , m_renderCtxInfo (renderCtxInfo)
528 , m_coordType (coordType)
529 , m_minFilter (minFilter)
533 , m_dataType (dataType)
535 , m_texture (DE_NULL)
536 , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
540 TextureCubeMipmapCase::~TextureCubeMipmapCase (void)
545 void TextureCubeMipmapCase::init (void)
547 if (m_coordType == COORDTYPE_PROJECTED && m_renderCtx.getRenderTarget().getNumSamples() > 0)
548 throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config");
550 m_texture = new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_size);
552 int numLevels = deLog2Floor32(m_size)+1;
554 // Fill texture with colored grid.
555 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
557 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
559 deUint32 step = 0xff / (numLevels-1);
560 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
561 deUint32 dec = 0xff - inc;
566 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
567 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
568 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
569 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
570 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
571 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
574 deUint32 color = 0xff000000 | rgb;
576 m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx);
577 tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
582 void TextureCubeMipmapCase::deinit (void)
590 static void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height)
592 const int minWidth = 8;
593 const int minHeight = 8;
595 bool partition = rnd.getFloat() > 0.4f;
596 bool partitionX = partition && width > minWidth && rnd.getBool();
597 bool partitionY = partition && height > minHeight && !partitionX;
601 int split = width/2 + rnd.getInt(-width/4, +width/4);
602 randomPartition(dst, rnd, x, y, split, height);
603 randomPartition(dst, rnd, x+split, y, width-split, height);
607 int split = height/2 + rnd.getInt(-height/4, +height/4);
608 randomPartition(dst, rnd, x, y, width, split);
609 randomPartition(dst, rnd, x, y+split, width, height-split);
612 dst.push_back(IVec4(x, y, width, height));
615 static void computeGridLayout (vector<IVec4>& dst, int width, int height)
618 randomPartition(dst, rnd, 0, 0, width, height);
621 TextureCubeMipmapCase::IterateResult TextureCubeMipmapCase::iterate (void)
623 const deUint32 magFilter = GL_NEAREST;
624 const int texWidth = m_texture->getRefTexture().getSize();
625 const int texHeight = m_texture->getRefTexture().getSize();
626 const int defViewportWidth = texWidth*2;
627 const int defViewportHeight = texHeight*2;
629 const glw::Functions& gl = m_renderCtx.getFunctions();
630 const RandomViewport viewport (m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
632 const bool isProjected = m_coordType == COORDTYPE_PROJECTED;
633 const bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS;
635 vector<float> texCoord;
636 tcu::Surface renderedFrame (viewport.width, viewport.height);
638 // Bail out if rendertarget is too small.
639 if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2)
640 throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
642 // Upload texture data.
645 // Bind gradient texture and setup sampler parameters.
646 gl.bindTexture (GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
647 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS);
648 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT);
649 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter);
650 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter);
652 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
655 vector<IVec4> gridLayout;
656 computeGridLayout(gridLayout, viewport.width, viewport.height);
659 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
661 // Projection values \note Less agressive than in 2D case due to smaller quads.
662 static const Vec4 s_projections[] =
664 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
665 Vec4(1.3f, 0.8f, 0.6f, 1.1f),
666 Vec4(0.8f, 1.0f, 1.2f, 0.8f),
667 Vec4(1.2f, 1.0f, 1.3f, 0.9f)
671 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
673 const int curX = gridLayout[cellNdx].x();
674 const int curY = gridLayout[cellNdx].y();
675 const int curW = gridLayout[cellNdx].z();
676 const int curH = gridLayout[cellNdx].w();
677 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
678 RenderParams params (TEXTURETYPE_CUBE);
680 DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported.
681 computeQuadTexCoordCube(texCoord, cubeFace);
685 params.flags |= ReferenceParams::PROJECTED;
686 params.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
691 params.flags |= ReferenceParams::USE_BIAS;
692 params.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
696 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
697 m_renderer.renderQuad(0, &texCoord[0], params);
699 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
702 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
703 GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
705 // Render reference and compare
707 tcu::Surface referenceFrame (viewport.width, viewport.height);
708 tcu::Surface errorMask (viewport.width, viewport.height);
709 int numFailedPixels = 0;
710 ReferenceParams params (TEXTURETYPE_CUBE);
711 tcu::LookupPrecision lookupPrec;
712 tcu::LodPrecision lodPrec (tcu::LodPrecision::RULE_OPENGL);
714 // Params for rendering reference
715 params.sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
716 params.sampler.seamlessCubeMap = true;
717 params.lodMode = LODMODE_EXACT;
719 // Comparison parameters
720 lookupPrec.colorMask = getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat());
721 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0)));
722 lookupPrec.coordBits = isProjected ? tcu::IVec3(8) : tcu::IVec3(10);
723 lookupPrec.uvwBits = tcu::IVec3(5,5,0);
724 lodPrec.derivateBits = 10;
725 lodPrec.lodBits = isProjected ? 3 : 6;
727 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
729 const int curX = gridLayout[cellNdx].x();
730 const int curY = gridLayout[cellNdx].y();
731 const int curW = gridLayout[cellNdx].z();
732 const int curH = gridLayout[cellNdx].w();
733 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
735 DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported.
736 computeQuadTexCoordCube(texCoord, cubeFace);
740 params.flags |= ReferenceParams::PROJECTED;
741 params.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
746 params.flags |= ReferenceParams::USE_BIAS;
747 params.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
750 // Render ideal reference.
752 tcu::SurfaceAccess idealDst(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY, curW, curH);
753 sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params);
757 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
758 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
759 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
760 m_texture->getRefTexture(), &texCoord[0], params,
761 lookupPrec, lodPrec, m_testCtx.getWatchDog());
764 if (numFailedPixels > 0)
765 m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
767 m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
768 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
770 if (numFailedPixels > 0)
772 m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
773 << TestLog::Image("ErrorMask", "Error mask", errorMask);
776 m_testCtx.getLog() << TestLog::EndImageSet;
779 const bool isOk = numFailedPixels == 0;
780 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
781 isOk ? "Pass" : "Image verification failed");
788 // Texture2DGenMipmapCase
790 class Texture2DGenMipmapCase : public tcu::TestCase
794 Texture2DGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int width, int height);
795 ~Texture2DGenMipmapCase (void);
799 IterateResult iterate (void);
802 Texture2DGenMipmapCase (const Texture2DGenMipmapCase& other);
803 Texture2DGenMipmapCase& operator= (const Texture2DGenMipmapCase& other);
805 glu::RenderContext& m_renderCtx;
813 glu::Texture2D* m_texture;
814 TextureRenderer m_renderer;
817 Texture2DGenMipmapCase::Texture2DGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int width, int height)
818 : TestCase (testCtx, name, desc)
819 , m_renderCtx (renderCtx)
821 , m_dataType (dataType)
825 , m_texture (DE_NULL)
826 , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
830 Texture2DGenMipmapCase::~Texture2DGenMipmapCase (void)
835 void Texture2DGenMipmapCase::init (void)
837 DE_ASSERT(!m_texture);
838 m_texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
841 void Texture2DGenMipmapCase::deinit (void)
849 Texture2DGenMipmapCase::IterateResult Texture2DGenMipmapCase::iterate (void)
851 const glw::Functions& gl = m_renderCtx.getFunctions();
853 const deUint32 minFilter = GL_NEAREST_MIPMAP_NEAREST;
854 const deUint32 magFilter = GL_NEAREST;
855 const deUint32 wrapS = GL_CLAMP_TO_EDGE;
856 const deUint32 wrapT = GL_CLAMP_TO_EDGE;
858 const int numLevels = deLog2Floor32(de::max(m_width, m_height))+1;
860 tcu::Texture2D resultTexture (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight());
862 vector<float> texCoord;
864 // Initialize texture level 0 with colored grid.
865 m_texture->getRefTexture().allocLevel(0);
866 tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 8, tcu::Vec4(1.0f, 0.5f, 0.0f, 0.5f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
868 // Upload data and setup params.
871 gl.bindTexture (GL_TEXTURE_2D, m_texture->getGLTexture());
872 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
873 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
874 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
875 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
876 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
879 gl.hint(GL_GENERATE_MIPMAP_HINT, m_hint);
880 gl.generateMipmap(GL_TEXTURE_2D);
881 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap()");
883 // Use (0, 0) -> (1, 1) texture coordinates.
884 computeQuadTexCoord2D(texCoord, Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f));
886 // Fetch resulting texture by rendering.
887 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
889 const int levelWidth = de::max(1, m_width >> levelNdx);
890 const int levelHeight = de::max(1, m_height >> levelNdx);
891 const RandomViewport viewport (m_renderCtx.getRenderTarget(), levelWidth, levelHeight, deStringHash(getName()) + levelNdx);
893 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
894 m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D);
896 resultTexture.allocLevel(levelNdx);
897 glu::readPixels(m_renderCtx, viewport.x, viewport.y, resultTexture.getLevel(levelNdx));
902 const IVec4 framebufferBits = max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0));
903 const IVec4 formatBits = tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
904 const tcu::BVec4 formatMask = greaterThan(formatBits, IVec4(0));
905 const IVec4 cmpBits = select(min(framebufferBits, formatBits), framebufferBits, formatMask);
906 GenMipmapPrecision comparePrec;
908 comparePrec.colorMask = getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat());
909 comparePrec.colorThreshold = tcu::computeFixedPointThreshold(cmpBits);
910 comparePrec.filterBits = tcu::IVec3(4, 4, 0);
912 const qpTestResult compareResult = compareGenMipmapResult(m_testCtx.getLog(), resultTexture, m_texture->getRefTexture(), comparePrec);
914 m_testCtx.setTestResult(compareResult, compareResult == QP_TEST_RESULT_PASS ? "Pass" :
915 compareResult == QP_TEST_RESULT_QUALITY_WARNING ? "Low-quality method used" :
916 compareResult == QP_TEST_RESULT_FAIL ? "Image comparison failed" : "");
922 // TextureCubeGenMipmapCase
924 class TextureCubeGenMipmapCase : public tcu::TestCase
928 TextureCubeGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int size);
929 ~TextureCubeGenMipmapCase (void);
933 IterateResult iterate (void);
936 TextureCubeGenMipmapCase (const TextureCubeGenMipmapCase& other);
937 TextureCubeGenMipmapCase& operator= (const TextureCubeGenMipmapCase& other);
939 glu::RenderContext& m_renderCtx;
946 glu::TextureCube* m_texture;
947 TextureRenderer m_renderer;
950 TextureCubeGenMipmapCase::TextureCubeGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int size)
951 : TestCase (testCtx, name, desc)
952 , m_renderCtx (renderCtx)
954 , m_dataType (dataType)
957 , m_texture (DE_NULL)
958 , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
962 TextureCubeGenMipmapCase::~TextureCubeGenMipmapCase (void)
967 void TextureCubeGenMipmapCase::init (void)
969 if (m_renderCtx.getRenderTarget().getWidth() < 3*m_size || m_renderCtx.getRenderTarget().getHeight() < 2*m_size)
970 throw tcu::NotSupportedError("Render target size must be at least (" + de::toString(3*m_size) + ", " + de::toString(2*m_size) + ")");
972 DE_ASSERT(!m_texture);
973 m_texture = new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_size);
976 void TextureCubeGenMipmapCase::deinit (void)
984 TextureCubeGenMipmapCase::IterateResult TextureCubeGenMipmapCase::iterate (void)
986 const glw::Functions& gl = m_renderCtx.getFunctions();
988 const deUint32 minFilter = GL_NEAREST_MIPMAP_NEAREST;
989 const deUint32 magFilter = GL_NEAREST;
990 const deUint32 wrapS = GL_CLAMP_TO_EDGE;
991 const deUint32 wrapT = GL_CLAMP_TO_EDGE;
993 tcu::TextureCube resultTexture (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_size);
995 const int numLevels = deLog2Floor32(m_size)+1;
996 vector<float> texCoord;
998 // Initialize texture level 0 with colored grid.
999 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1001 Vec4 ca, cb; // Grid colors.
1005 case 0: ca = Vec4(1.0f, 0.3f, 0.0f, 0.7f); cb = Vec4(0.0f, 0.0f, 1.0f, 1.0f); break;
1006 case 1: ca = Vec4(0.0f, 1.0f, 0.5f, 0.5f); cb = Vec4(1.0f, 0.0f, 0.0f, 1.0f); break;
1007 case 2: ca = Vec4(0.7f, 0.0f, 1.0f, 0.3f); cb = Vec4(0.0f, 1.0f, 0.0f, 1.0f); break;
1008 case 3: ca = Vec4(0.0f, 0.3f, 1.0f, 1.0f); cb = Vec4(1.0f, 0.0f, 0.0f, 0.7f); break;
1009 case 4: ca = Vec4(1.0f, 0.0f, 0.5f, 1.0f); cb = Vec4(0.0f, 1.0f, 0.0f, 0.5f); break;
1010 case 5: ca = Vec4(0.7f, 1.0f, 0.0f, 1.0f); cb = Vec4(0.0f, 0.0f, 1.0f, 0.3f); break;
1013 m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
1014 fillWithGrid(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), 8, ca, cb);
1017 // Upload data and setup params.
1018 m_texture->upload();
1020 gl.bindTexture (GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
1021 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrapS);
1022 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrapT);
1023 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, minFilter);
1024 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter);
1025 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
1028 gl.hint(GL_GENERATE_MIPMAP_HINT, m_hint);
1029 gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
1030 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap()");
1032 // Render all levels.
1033 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1035 const int levelWidth = de::max(1, m_size >> levelNdx);
1036 const int levelHeight = de::max(1, m_size >> levelNdx);
1038 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1040 const RandomViewport viewport (m_renderCtx.getRenderTarget(), levelWidth*3, levelHeight*2, deStringHash(getName()) ^ deInt32Hash(levelNdx + faceNdx));
1041 const tcu::CubeFace face = tcu::CubeFace(faceNdx);
1043 computeQuadTexCoordCube(texCoord, face);
1045 gl.viewport(viewport.x, viewport.y, levelWidth, levelHeight);
1046 m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE);
1048 resultTexture.allocLevel(face, levelNdx);
1049 glu::readPixels(m_renderCtx, viewport.x, viewport.y, resultTexture.getLevelFace(levelNdx, face));
1055 const IVec4 framebufferBits = max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0));
1056 const IVec4 formatBits = tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
1057 const tcu::BVec4 formatMask = greaterThan(formatBits, IVec4(0));
1058 const IVec4 cmpBits = select(min(framebufferBits, formatBits), framebufferBits, formatMask);
1059 GenMipmapPrecision comparePrec;
1061 comparePrec.colorMask = getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat());
1062 comparePrec.colorThreshold = tcu::computeFixedPointThreshold(cmpBits);
1063 comparePrec.filterBits = tcu::IVec3(4, 4, 0);
1065 const qpTestResult compareResult = compareGenMipmapResult(m_testCtx.getLog(), resultTexture, m_texture->getRefTexture(), comparePrec);
1067 m_testCtx.setTestResult(compareResult, compareResult == QP_TEST_RESULT_PASS ? "Pass" :
1068 compareResult == QP_TEST_RESULT_QUALITY_WARNING ? "Low-quality method used" :
1069 compareResult == QP_TEST_RESULT_FAIL ? "Image comparison failed" : "");
1075 // Texture3DMipmapCase
1077 class Texture3DMipmapCase : public TestCase
1081 Texture3DMipmapCase (Context& context,
1084 CoordType coordType,
1093 ~Texture3DMipmapCase (void);
1097 IterateResult iterate (void);
1100 Texture3DMipmapCase (const Texture3DMipmapCase& other);
1101 Texture3DMipmapCase& operator= (const Texture3DMipmapCase& other);
1103 CoordType m_coordType;
1104 deUint32 m_minFilter;
1108 deUint32 m_internalFormat;
1113 glu::Texture3D* m_texture;
1114 TextureTestUtil::TextureRenderer m_renderer;
1117 Texture3DMipmapCase::Texture3DMipmapCase (Context& context, const char* name, const char* desc, CoordType coordType, deUint32 minFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR, deUint32 format, int width, int height, int depth)
1118 : TestCase (context, name, desc)
1119 , m_coordType (coordType)
1120 , m_minFilter (minFilter)
1124 , m_internalFormat (format)
1128 , m_texture (DE_NULL)
1129 , m_renderer (context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1133 Texture3DMipmapCase::~Texture3DMipmapCase (void)
1135 Texture3DMipmapCase::deinit();
1138 void Texture3DMipmapCase::init (void)
1140 const tcu::TextureFormat& texFmt = glu::mapGLInternalFormat(m_internalFormat);
1141 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
1142 const tcu::Vec4& cScale = fmtInfo.lookupScale;
1143 const tcu::Vec4& cBias = fmtInfo.lookupBias;
1144 int numLevels = deLog2Floor32(de::max(de::max(m_width, m_height), m_depth))+1;
1146 if (m_coordType == COORDTYPE_PROJECTED && m_context.getRenderTarget().getNumSamples() > 0)
1147 throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config");
1149 m_texture = new glu::Texture3D(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);
1151 // Fill texture with colored grid.
1152 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1154 deUint32 step = 0xff / (numLevels-1);
1155 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1156 deUint32 dec = 0xff - inc;
1157 deUint32 rgb = (0xff << 16) | (dec << 8) | inc;
1158 deUint32 color = 0xff000000 | rgb;
1160 m_texture->getRefTexture().allocLevel(levelNdx);
1161 tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec()*cScale + cBias);
1164 m_texture->upload();
1167 void Texture3DMipmapCase::deinit (void)
1170 m_texture = DE_NULL;
1175 static void getBasicTexCoord3D (std::vector<float>& dst, int cellNdx)
1187 // sScale sBias tScale tBias rScale rBias
1188 { 0.9f, -0.1f, 0.7f, 0.3f, 0.8f, 0.9f },
1189 { 1.2f, -0.1f, 1.1f, 0.3f, 1.0f, 0.9f },
1190 { 1.5f, 0.7f, 0.9f, -0.3f, 1.1f, 0.1f },
1191 { 1.2f, 0.7f, -2.3f, -0.3f, 1.1f, 0.2f },
1192 { 1.1f, 0.8f, -1.3f, -0.3f, 2.9f, 0.9f },
1193 { 3.4f, 0.8f, 4.0f, 0.0f, -3.3f, -1.0f },
1194 { -3.4f, -0.1f, -4.0f, 0.0f, -5.1f, 1.0f },
1195 { -4.0f, -0.1f, 3.4f, 0.1f, 5.7f, 0.0f },
1196 { -5.6f, 0.0f, 0.5f, 1.2f, 3.9f, 4.0f },
1197 { 5.0f, -2.0f, 3.1f, 1.2f, 5.1f, 0.2f },
1198 { 2.5f, -2.0f, 6.3f, 3.0f, 5.1f, 0.2f },
1199 { -8.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f },
1200 { 3.8f, 0.0f, 9.7f, 1.0f, 7.0f, 0.7f },
1201 { 13.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f },
1202 { 16.0f, 8.0f, 12.7f, 1.0f, 17.1f, 0.7f },
1203 { 15.3f, 0.0f, 20.1f, 3.0f, 33.0f, 3.2f }
1206 float sScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sScale;
1207 float sBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sBias;
1208 float tScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tScale;
1209 float tBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tBias;
1210 float rScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rScale;
1211 float rBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rBias;
1215 dst[0] = sBias; dst[ 1] = tBias; dst[ 2] = rBias;
1216 dst[3] = sBias; dst[ 4] = tBias+tScale; dst[ 5] = rBias+rScale*0.5f;
1217 dst[6] = sBias+sScale; dst[ 7] = tBias; dst[ 8] = rBias+rScale*0.5f;
1218 dst[9] = sBias+sScale; dst[10] = tBias+tScale; dst[11] = rBias+rScale;
1221 static void getAffineTexCoord3D (std::vector<float>& dst, int cellNdx)
1223 // Use basic coords as base.
1224 getBasicTexCoord3D(dst, cellNdx);
1226 // Rotate based on cell index.
1227 float angleX = 0.0f + 2.0f*DE_PI * ((float)cellNdx / 16.0f);
1228 float angleY = 1.0f + 2.0f*DE_PI * ((float)cellNdx / 32.0f);
1229 tcu::Mat3 rotMatrix = tcu::rotationMatrixX(angleX) * tcu::rotationMatrixY(angleY);
1231 Vec3 p0 = rotMatrix * Vec3(dst[0], dst[ 1], dst[ 2]);
1232 Vec3 p1 = rotMatrix * Vec3(dst[3], dst[ 4], dst[ 5]);
1233 Vec3 p2 = rotMatrix * Vec3(dst[6], dst[ 7], dst[ 8]);
1234 Vec3 p3 = rotMatrix * Vec3(dst[9], dst[10], dst[11]);
1236 dst[0] = p0.x(); dst[ 1] = p0.y(); dst[ 2] = p0.z();
1237 dst[3] = p1.x(); dst[ 4] = p1.y(); dst[ 5] = p1.z();
1238 dst[6] = p2.x(); dst[ 7] = p2.y(); dst[ 8] = p2.z();
1239 dst[9] = p3.x(); dst[10] = p3.y(); dst[11] = p3.z();
1242 Texture3DMipmapCase::IterateResult Texture3DMipmapCase::iterate (void)
1244 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1246 const tcu::Texture3D& refTexture = m_texture->getRefTexture();
1247 const tcu::TextureFormat& texFmt = refTexture.getFormat();
1248 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
1249 const int texWidth = refTexture.getWidth();
1250 const int texHeight = refTexture.getHeight();
1251 const deUint32 magFilter = GL_NEAREST;
1253 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
1254 const RandomViewport viewport (renderTarget, texWidth*4, texHeight*4, deStringHash(getName()));
1256 const bool isProjected = m_coordType == COORDTYPE_PROJECTED;
1257 const bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS;
1259 // Viewport is divided into 4x4 grid.
1260 const int gridWidth = 4;
1261 const int gridHeight = 4;
1262 const int cellWidth = viewport.width / gridWidth;
1263 const int cellHeight = viewport.height / gridHeight;
1265 ReferenceParams sampleParams (TEXTURETYPE_3D);
1267 tcu::Surface renderedFrame (viewport.width, viewport.height);
1268 vector<float> texCoord;
1270 // Sampling parameters.
1271 sampleParams.sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapR, m_minFilter, magFilter);
1272 sampleParams.samplerType = getSamplerType(texFmt);
1273 sampleParams.colorBias = fmtInfo.lookupBias;
1274 sampleParams.colorScale = fmtInfo.lookupScale;
1275 sampleParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
1277 // Bind texture and setup sampler parameters.
1278 gl.bindTexture (GL_TEXTURE_3D, m_texture->getGLTexture());
1279 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, m_wrapS);
1280 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, m_wrapT);
1281 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, m_wrapR);
1282 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, m_minFilter);
1283 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, magFilter);
1285 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
1288 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
1290 // Projection values.
1291 static const Vec4 s_projections[] =
1293 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
1294 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
1295 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
1296 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
1300 for (int gridY = 0; gridY < gridHeight; gridY++)
1302 for (int gridX = 0; gridX < gridWidth; gridX++)
1304 const int curX = cellWidth*gridX;
1305 const int curY = cellHeight*gridY;
1306 const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
1307 const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
1308 const int cellNdx = gridY*gridWidth + gridX;
1310 // Compute texcoord.
1311 switch (m_coordType)
1313 case COORDTYPE_BASIC_BIAS: // Fall-through.
1314 case COORDTYPE_PROJECTED:
1315 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break;
1316 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break;
1317 default: DE_ASSERT(DE_FALSE);
1322 sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
1326 sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
1329 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
1330 m_renderer.renderQuad(0, &texCoord[0], sampleParams);
1335 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
1339 const tcu::PixelFormat& pixelFormat = m_context.getRenderTarget().getPixelFormat();
1340 const bool isTrilinear = m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
1341 tcu::Surface referenceFrame (viewport.width, viewport.height);
1342 tcu::Surface errorMask (viewport.width, viewport.height);
1343 tcu::LookupPrecision lookupPrec;
1344 tcu::LodPrecision lodPrec (tcu::LodPrecision::RULE_OPENGL);
1345 int numFailedPixels = 0;
1347 lookupPrec.coordBits = tcu::IVec3(20, 20, 20);
1348 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
1349 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
1350 lookupPrec.colorMask = getCompareMask(pixelFormat);
1351 lodPrec.derivateBits = 10;
1352 lodPrec.lodBits = isProjected ? 6 : 8;
1354 for (int gridY = 0; gridY < gridHeight; gridY++)
1356 for (int gridX = 0; gridX < gridWidth; gridX++)
1358 const int curX = cellWidth*gridX;
1359 const int curY = cellHeight*gridY;
1360 const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
1361 const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
1362 const int cellNdx = gridY*gridWidth + gridX;
1364 switch (m_coordType)
1366 case COORDTYPE_BASIC_BIAS: // Fall-through.
1367 case COORDTYPE_PROJECTED:
1368 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break;
1369 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break;
1370 default: DE_ASSERT(DE_FALSE);
1374 sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
1377 sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
1379 // Render ideal result
1380 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
1381 refTexture, &texCoord[0], sampleParams);
1383 // Compare this cell
1384 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1385 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1386 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1387 m_texture->getRefTexture(), &texCoord[0], sampleParams,
1388 lookupPrec, lodPrec, m_testCtx.getWatchDog());
1392 if (numFailedPixels > 0)
1393 m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1395 m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
1396 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1398 if (numFailedPixels > 0)
1400 m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1401 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1404 m_testCtx.getLog() << TestLog::EndImageSet;
1407 const bool isOk = numFailedPixels == 0;
1408 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1409 isOk ? "Pass" : "Image verification failed");
1416 // Texture2DLodControlCase + test cases
1418 class Texture2DLodControlCase : public TestCase
1422 Texture2DLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter);
1423 ~Texture2DLodControlCase (void);
1427 IterateResult iterate (void);
1430 virtual void setTextureParams (int cellNdx) = DE_NULL;
1431 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
1433 const int m_texWidth;
1434 const int m_texHeight;
1437 Texture2DLodControlCase (const Texture2DLodControlCase& other);
1438 Texture2DLodControlCase& operator= (const Texture2DLodControlCase& other);
1440 deUint32 m_minFilter;
1442 glu::Texture2D* m_texture;
1443 TextureTestUtil::TextureRenderer m_renderer;
1446 Texture2DLodControlCase::Texture2DLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1447 : TestCase (context, name, desc)
1450 , m_minFilter (minFilter)
1451 , m_texture (DE_NULL)
1452 , m_renderer (context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1456 Texture2DLodControlCase::~Texture2DLodControlCase (void)
1458 Texture2DLodControlCase::deinit();
1461 void Texture2DLodControlCase::init (void)
1463 const deUint32 format = GL_RGBA8;
1464 int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1466 m_texture = new glu::Texture2D(m_context.getRenderContext(), format, m_texWidth, m_texHeight);
1468 // Fill texture with colored grid.
1469 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1471 deUint32 step = 0xff / (numLevels-1);
1472 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1473 deUint32 dec = 0xff - inc;
1474 deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
1475 deUint32 color = 0xff000000 | rgb;
1477 m_texture->getRefTexture().allocLevel(levelNdx);
1478 tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec());
1482 void Texture2DLodControlCase::deinit (void)
1485 m_texture = DE_NULL;
1490 Texture2DLodControlCase::IterateResult Texture2DLodControlCase::iterate (void)
1492 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1494 const deUint32 wrapS = GL_REPEAT;
1495 const deUint32 wrapT = GL_REPEAT;
1496 const deUint32 magFilter = GL_NEAREST;
1498 const tcu::Texture2D& refTexture = m_texture->getRefTexture();
1499 const int texWidth = refTexture.getWidth();
1500 const int texHeight = refTexture.getHeight();
1502 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
1503 const RandomViewport viewport (renderTarget, texWidth*4, texHeight*4, deStringHash(getName()));
1505 ReferenceParams sampleParams (TEXTURETYPE_2D, glu::mapGLSampler(wrapS, wrapT, m_minFilter, magFilter));
1506 vector<float> texCoord;
1507 tcu::Surface renderedFrame (viewport.width, viewport.height);
1509 // Viewport is divided into 4x4 grid.
1510 const int gridWidth = 4;
1511 const int gridHeight = 4;
1512 const int cellWidth = viewport.width / gridWidth;
1513 const int cellHeight = viewport.height / gridHeight;
1515 // Upload texture data.
1516 m_texture->upload();
1518 // Bind gradient texture and setup sampler parameters.
1519 gl.bindTexture (GL_TEXTURE_2D, m_texture->getGLTexture());
1520 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
1521 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
1522 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
1523 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
1525 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
1528 for (int gridY = 0; gridY < gridHeight; gridY++)
1530 for (int gridX = 0; gridX < gridWidth; gridX++)
1532 int curX = cellWidth*gridX;
1533 int curY = cellHeight*gridY;
1534 int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
1535 int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
1536 int cellNdx = gridY*gridWidth + gridX;
1538 // Compute texcoord.
1539 getBasicTexCoord2D(texCoord, cellNdx);
1542 setTextureParams(cellNdx);
1543 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
1544 m_renderer.renderQuad(0, &texCoord[0], sampleParams);
1548 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
1549 GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
1553 const tcu::PixelFormat& pixelFormat = m_context.getRenderTarget().getPixelFormat();
1554 const bool isTrilinear = m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
1555 tcu::Surface referenceFrame (viewport.width, viewport.height);
1556 tcu::Surface errorMask (viewport.width, viewport.height);
1557 tcu::LookupPrecision lookupPrec;
1558 tcu::LodPrecision lodPrec (tcu::LodPrecision::RULE_OPENGL);
1559 int numFailedPixels = 0;
1561 lookupPrec.coordBits = tcu::IVec3(20, 20, 0);
1562 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
1563 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
1564 lookupPrec.colorMask = getCompareMask(pixelFormat);
1565 lodPrec.derivateBits = 10;
1566 lodPrec.lodBits = 8;
1568 for (int gridY = 0; gridY < gridHeight; gridY++)
1570 for (int gridX = 0; gridX < gridWidth; gridX++)
1572 const int curX = cellWidth*gridX;
1573 const int curY = cellHeight*gridY;
1574 const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
1575 const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
1576 const int cellNdx = gridY*gridWidth + gridX;
1578 getBasicTexCoord2D(texCoord, cellNdx);
1579 getReferenceParams(sampleParams, cellNdx);
1581 // Render ideal result
1582 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
1583 refTexture, &texCoord[0], sampleParams);
1585 // Compare this cell
1586 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1587 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1588 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1589 m_texture->getRefTexture(), &texCoord[0], sampleParams,
1590 lookupPrec, lodPrec, m_testCtx.getWatchDog());
1594 if (numFailedPixels > 0)
1595 m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1597 m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
1598 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1600 if (numFailedPixels > 0)
1602 m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1603 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1606 m_testCtx.getLog() << TestLog::EndImageSet;
1609 const bool isOk = numFailedPixels == 0;
1610 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1611 isOk ? "Pass" : "Image verification failed");
1618 class Texture2DMinLodCase : public Texture2DLodControlCase
1621 Texture2DMinLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1622 : Texture2DLodControlCase(context, name, desc, minFilter)
1627 void setTextureParams (int cellNdx)
1629 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1630 gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, getMinLodForCell(cellNdx));
1633 void getReferenceParams (ReferenceParams& params, int cellNdx)
1635 params.minLod = getMinLodForCell(cellNdx);
1639 class Texture2DMaxLodCase : public Texture2DLodControlCase
1642 Texture2DMaxLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1643 : Texture2DLodControlCase(context, name, desc, minFilter)
1648 void setTextureParams (int cellNdx)
1650 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1651 gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, getMaxLodForCell(cellNdx));
1654 void getReferenceParams (ReferenceParams& params, int cellNdx)
1656 params.maxLod = getMaxLodForCell(cellNdx);
1660 class Texture2DBaseLevelCase : public Texture2DLodControlCase
1663 Texture2DBaseLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1664 : Texture2DLodControlCase(context, name, desc, minFilter)
1669 int getBaseLevel (int cellNdx) const
1671 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1672 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0xac2f274a) % numLevels;
1677 void setTextureParams (int cellNdx)
1679 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1680 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, getBaseLevel(cellNdx));
1683 void getReferenceParams (ReferenceParams& params, int cellNdx)
1685 params.baseLevel = getBaseLevel(cellNdx);
1689 class Texture2DMaxLevelCase : public Texture2DLodControlCase
1692 Texture2DMaxLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1693 : Texture2DLodControlCase(context, name, desc, minFilter)
1698 int getMaxLevel (int cellNdx) const
1700 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1701 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x82cfa4e) % numLevels;
1706 void setTextureParams (int cellNdx)
1708 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1709 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, getMaxLevel(cellNdx));
1712 void getReferenceParams (ReferenceParams& params, int cellNdx)
1714 params.maxLevel = getMaxLevel(cellNdx);
1718 // TextureCubeLodControlCase + test cases
1720 class TextureCubeLodControlCase : public TestCase
1724 TextureCubeLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter);
1725 ~TextureCubeLodControlCase (void);
1729 IterateResult iterate (void);
1732 virtual void setTextureParams (int cellNdx) = DE_NULL;
1733 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
1735 const int m_texSize;
1738 TextureCubeLodControlCase (const TextureCubeLodControlCase& other);
1739 TextureCubeLodControlCase& operator= (const TextureCubeLodControlCase& other);
1741 deUint32 m_minFilter;
1743 glu::TextureCube* m_texture;
1744 TextureTestUtil::TextureRenderer m_renderer;
1747 TextureCubeLodControlCase::TextureCubeLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1748 : TestCase (context, name, desc)
1750 , m_minFilter (minFilter)
1751 , m_texture (DE_NULL)
1752 , m_renderer (context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1756 TextureCubeLodControlCase::~TextureCubeLodControlCase (void)
1761 void TextureCubeLodControlCase::init (void)
1763 const deUint32 format = GL_RGBA8;
1764 const int numLevels = deLog2Floor32(m_texSize)+1;
1766 m_texture = new glu::TextureCube(m_context.getRenderContext(), format, m_texSize);
1768 // Fill texture with colored grid.
1769 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1771 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1773 deUint32 step = 0xff / (numLevels-1);
1774 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1775 deUint32 dec = 0xff - inc;
1780 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
1781 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
1782 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
1783 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
1784 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
1785 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
1788 deUint32 color = 0xff000000 | rgb;
1790 m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx);
1791 tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
1796 void TextureCubeLodControlCase::deinit (void)
1799 m_texture = DE_NULL;
1804 TextureCubeLodControlCase::IterateResult TextureCubeLodControlCase::iterate (void)
1806 const deUint32 wrapS = GL_CLAMP_TO_EDGE;
1807 const deUint32 wrapT = GL_CLAMP_TO_EDGE;
1808 const deUint32 magFilter = GL_NEAREST;
1810 const int texWidth = m_texture->getRefTexture().getSize();
1811 const int texHeight = m_texture->getRefTexture().getSize();
1813 const int defViewportWidth = texWidth*2;
1814 const int defViewportHeight = texHeight*2;
1816 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1817 const RandomViewport viewport (m_context.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
1819 vector<float> texCoord;
1821 tcu::Surface renderedFrame (viewport.width, viewport.height);
1823 // Upload texture data.
1824 m_texture->upload();
1826 // Bind gradient texture and setup sampler parameters.
1827 gl.bindTexture (GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
1828 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrapS);
1829 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrapT);
1830 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter);
1831 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter);
1833 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
1836 vector<tcu::IVec4> gridLayout;
1837 computeGridLayout(gridLayout, viewport.width, viewport.height);
1839 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
1841 const int curX = gridLayout[cellNdx].x();
1842 const int curY = gridLayout[cellNdx].y();
1843 const int curW = gridLayout[cellNdx].z();
1844 const int curH = gridLayout[cellNdx].w();
1845 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
1846 RenderParams params (TEXTURETYPE_CUBE);
1848 computeQuadTexCoordCube(texCoord, cubeFace);
1850 setTextureParams(cellNdx);
1853 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
1854 m_renderer.renderQuad(0, &texCoord[0], params);
1855 GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
1859 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
1860 GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
1862 // Render reference and compare
1864 tcu::Surface referenceFrame (viewport.width, viewport.height);
1865 tcu::Surface errorMask (viewport.width, viewport.height);
1866 int numFailedPixels = 0;
1867 ReferenceParams params (TEXTURETYPE_CUBE);
1868 tcu::LookupPrecision lookupPrec;
1869 tcu::LodPrecision lodPrec (tcu::LodPrecision::RULE_OPENGL);
1871 // Params for rendering reference
1872 params.sampler = glu::mapGLSampler(wrapS, wrapT, m_minFilter, magFilter);
1873 params.sampler.seamlessCubeMap = true;
1874 params.lodMode = LODMODE_EXACT;
1876 // Comparison parameters
1877 lookupPrec.colorMask = getCompareMask(m_context.getRenderTarget().getPixelFormat());
1878 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(m_context.getRenderTarget().getPixelFormat())-2, IVec4(0)));
1879 lookupPrec.coordBits = tcu::IVec3(10);
1880 lookupPrec.uvwBits = tcu::IVec3(5,5,0);
1881 lodPrec.derivateBits = 10;
1882 lodPrec.lodBits = 6;
1884 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
1886 const int curX = gridLayout[cellNdx].x();
1887 const int curY = gridLayout[cellNdx].y();
1888 const int curW = gridLayout[cellNdx].z();
1889 const int curH = gridLayout[cellNdx].w();
1890 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
1892 computeQuadTexCoordCube(texCoord, cubeFace);
1893 getReferenceParams(params, cellNdx);
1895 // Render ideal reference.
1897 tcu::SurfaceAccess idealDst(referenceFrame, m_context.getRenderTarget().getPixelFormat(), curX, curY, curW, curH);
1898 sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params);
1901 // Compare this cell
1902 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1903 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1904 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1905 m_texture->getRefTexture(), &texCoord[0], params,
1906 lookupPrec, lodPrec, m_testCtx.getWatchDog());
1909 if (numFailedPixels > 0)
1910 m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1912 m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
1913 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1915 if (numFailedPixels > 0)
1917 m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1918 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1921 m_testCtx.getLog() << TestLog::EndImageSet;
1924 const bool isOk = numFailedPixels == 0;
1925 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1926 isOk ? "Pass" : "Image verification failed");
1933 class TextureCubeMinLodCase : public TextureCubeLodControlCase
1936 TextureCubeMinLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1937 : TextureCubeLodControlCase(context, name, desc, minFilter)
1942 void setTextureParams (int cellNdx)
1944 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1945 gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD, getMinLodForCell(cellNdx));
1948 void getReferenceParams (ReferenceParams& params, int cellNdx)
1950 params.minLod = getMinLodForCell(cellNdx);
1954 class TextureCubeMaxLodCase : public TextureCubeLodControlCase
1957 TextureCubeMaxLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1958 : TextureCubeLodControlCase(context, name, desc, minFilter)
1963 void setTextureParams (int cellNdx)
1965 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1966 gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD, getMaxLodForCell(cellNdx));
1969 void getReferenceParams (ReferenceParams& params, int cellNdx)
1971 params.maxLod = getMaxLodForCell(cellNdx);
1975 class TextureCubeBaseLevelCase : public TextureCubeLodControlCase
1978 TextureCubeBaseLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
1979 : TextureCubeLodControlCase(context, name, desc, minFilter)
1984 int getBaseLevel (int cellNdx) const
1986 const int numLevels = deLog2Floor32(m_texSize)+1;
1987 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x23fae13) % numLevels;
1992 void setTextureParams (int cellNdx)
1994 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1995 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, getBaseLevel(cellNdx));
1998 void getReferenceParams (ReferenceParams& params, int cellNdx)
2000 params.baseLevel = getBaseLevel(cellNdx);
2004 class TextureCubeMaxLevelCase : public TextureCubeLodControlCase
2007 TextureCubeMaxLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
2008 : TextureCubeLodControlCase(context, name, desc, minFilter)
2013 int getMaxLevel (int cellNdx) const
2015 const int numLevels = deLog2Floor32(m_texSize)+1;
2016 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x974e21) % numLevels;
2021 void setTextureParams (int cellNdx)
2023 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2024 gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, getMaxLevel(cellNdx));
2027 void getReferenceParams (ReferenceParams& params, int cellNdx)
2029 params.maxLevel = getMaxLevel(cellNdx);
2033 // Texture3DLodControlCase + test cases
2035 class Texture3DLodControlCase : public TestCase
2039 Texture3DLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter);
2040 ~Texture3DLodControlCase (void);
2044 IterateResult iterate (void);
2047 virtual void setTextureParams (int cellNdx) = DE_NULL;
2048 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
2050 const int m_texWidth;
2051 const int m_texHeight;
2052 const int m_texDepth;
2055 Texture3DLodControlCase (const Texture3DLodControlCase& other);
2056 Texture3DLodControlCase& operator= (const Texture3DLodControlCase& other);
2058 deUint32 m_minFilter;
2060 glu::Texture3D* m_texture;
2061 TextureTestUtil::TextureRenderer m_renderer;
2064 Texture3DLodControlCase::Texture3DLodControlCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
2065 : TestCase (context, name, desc)
2069 , m_minFilter (minFilter)
2070 , m_texture (DE_NULL)
2071 , m_renderer (context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
2075 Texture3DLodControlCase::~Texture3DLodControlCase (void)
2077 Texture3DLodControlCase::deinit();
2080 void Texture3DLodControlCase::init (void)
2082 const deUint32 format = GL_RGBA8;
2083 const tcu::TextureFormat& texFmt = glu::mapGLInternalFormat(format);
2084 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
2085 const tcu::Vec4& cScale = fmtInfo.lookupScale;
2086 const tcu::Vec4& cBias = fmtInfo.lookupBias;
2087 int numLevels = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth))+1;
2089 m_texture = new glu::Texture3D(m_context.getRenderContext(), format, m_texWidth, m_texHeight, m_texDepth);
2091 // Fill texture with colored grid.
2092 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
2094 deUint32 step = 0xff / (numLevels-1);
2095 deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
2096 deUint32 dec = 0xff - inc;
2097 deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
2098 deUint32 color = 0xff000000 | rgb;
2100 m_texture->getRefTexture().allocLevel(levelNdx);
2101 tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec()*cScale + cBias);
2104 m_texture->upload();
2107 void Texture3DLodControlCase::deinit (void)
2110 m_texture = DE_NULL;
2115 Texture3DLodControlCase::IterateResult Texture3DLodControlCase::iterate (void)
2117 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2119 const deUint32 wrapS = GL_CLAMP_TO_EDGE;
2120 const deUint32 wrapT = GL_CLAMP_TO_EDGE;
2121 const deUint32 wrapR = GL_CLAMP_TO_EDGE;
2122 const deUint32 magFilter = GL_NEAREST;
2123 const tcu::Texture3D& refTexture = m_texture->getRefTexture();
2124 const tcu::TextureFormat& texFmt = refTexture.getFormat();
2125 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
2126 const int texWidth = refTexture.getWidth();
2127 const int texHeight = refTexture.getHeight();
2129 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
2130 const RandomViewport viewport (renderTarget, texWidth*4, texHeight*4, deStringHash(getName()));
2132 // Viewport is divided into 4x4 grid.
2133 const int gridWidth = 4;
2134 const int gridHeight = 4;
2135 const int cellWidth = viewport.width / gridWidth;
2136 const int cellHeight = viewport.height / gridHeight;
2138 tcu::Surface renderedFrame (viewport.width, viewport.height);
2139 vector<float> texCoord;
2140 ReferenceParams sampleParams (TEXTURETYPE_3D);
2142 // Sampling parameters.
2143 sampleParams.sampler = glu::mapGLSampler(wrapS, wrapT, wrapR, m_minFilter, magFilter);
2144 sampleParams.samplerType = getSamplerType(texFmt);
2145 sampleParams.colorBias = fmtInfo.lookupBias;
2146 sampleParams.colorScale = fmtInfo.lookupScale;
2148 // Bind texture and setup sampler parameters.
2149 gl.bindTexture (GL_TEXTURE_3D, m_texture->getGLTexture());
2150 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, wrapS);
2151 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, wrapT);
2152 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, wrapR);
2153 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, m_minFilter);
2154 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, magFilter);
2156 GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");
2159 for (int gridY = 0; gridY < gridHeight; gridY++)
2161 for (int gridX = 0; gridX < gridWidth; gridX++)
2163 int curX = cellWidth*gridX;
2164 int curY = cellHeight*gridY;
2165 int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
2166 int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
2167 int cellNdx = gridY*gridWidth + gridX;
2169 // Compute texcoord.
2170 getBasicTexCoord3D(texCoord, cellNdx);
2172 setTextureParams(cellNdx);
2175 gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH);
2176 m_renderer.renderQuad(0, &texCoord[0], sampleParams);
2181 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
2185 const tcu::PixelFormat& pixelFormat = m_context.getRenderTarget().getPixelFormat();
2186 const bool isTrilinear = m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
2187 tcu::Surface referenceFrame (viewport.width, viewport.height);
2188 tcu::Surface errorMask (viewport.width, viewport.height);
2189 tcu::LookupPrecision lookupPrec;
2190 tcu::LodPrecision lodPrec (tcu::LodPrecision::RULE_OPENGL);
2191 int numFailedPixels = 0;
2193 lookupPrec.coordBits = tcu::IVec3(20, 20, 20);
2194 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
2195 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
2196 lookupPrec.colorMask = getCompareMask(pixelFormat);
2197 lodPrec.derivateBits = 10;
2198 lodPrec.lodBits = 8;
2200 for (int gridY = 0; gridY < gridHeight; gridY++)
2202 for (int gridX = 0; gridX < gridWidth; gridX++)
2204 const int curX = cellWidth*gridX;
2205 const int curY = cellHeight*gridY;
2206 const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth;
2207 const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight;
2208 const int cellNdx = gridY*gridWidth + gridX;
2210 getBasicTexCoord3D(texCoord, cellNdx);
2211 getReferenceParams(sampleParams, cellNdx);
2213 // Render ideal result
2214 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
2215 refTexture, &texCoord[0], sampleParams);
2217 // Compare this cell
2218 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
2219 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
2220 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
2221 m_texture->getRefTexture(), &texCoord[0], sampleParams,
2222 lookupPrec, lodPrec, m_testCtx.getWatchDog());
2226 if (numFailedPixels > 0)
2227 m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
2229 m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result")
2230 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
2232 if (numFailedPixels > 0)
2234 m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
2235 << TestLog::Image("ErrorMask", "Error mask", errorMask);
2238 m_testCtx.getLog() << TestLog::EndImageSet;
2241 const bool isOk = numFailedPixels == 0;
2242 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
2243 isOk ? "Pass" : "Image verification failed");
2250 class Texture3DMinLodCase : public Texture3DLodControlCase
2253 Texture3DMinLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
2254 : Texture3DLodControlCase(context, name, desc, minFilter)
2259 void setTextureParams (int cellNdx)
2261 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2262 gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD, getMinLodForCell(cellNdx));
2265 void getReferenceParams (ReferenceParams& params, int cellNdx)
2267 params.minLod = getMinLodForCell(cellNdx);
2271 class Texture3DMaxLodCase : public Texture3DLodControlCase
2274 Texture3DMaxLodCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
2275 : Texture3DLodControlCase(context, name, desc, minFilter)
2280 void setTextureParams (int cellNdx)
2282 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2283 gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD, getMaxLodForCell(cellNdx));
2286 void getReferenceParams (ReferenceParams& params, int cellNdx)
2288 params.maxLod = getMaxLodForCell(cellNdx);
2292 class Texture3DBaseLevelCase : public Texture3DLodControlCase
2295 Texture3DBaseLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
2296 : Texture3DLodControlCase(context, name, desc, minFilter)
2301 int getBaseLevel (int cellNdx) const
2303 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
2304 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x7347e9) % numLevels;
2309 void setTextureParams (int cellNdx)
2311 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2312 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, getBaseLevel(cellNdx));
2315 void getReferenceParams (ReferenceParams& params, int cellNdx)
2317 params.baseLevel = getBaseLevel(cellNdx);
2321 class Texture3DMaxLevelCase : public Texture3DLodControlCase
2324 Texture3DMaxLevelCase (Context& context, const char* name, const char* desc, deUint32 minFilter)
2325 : Texture3DLodControlCase(context, name, desc, minFilter)
2330 int getMaxLevel (int cellNdx) const
2332 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
2333 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(getName()) ^ 0x9111e7) % numLevels;
2338 void setTextureParams (int cellNdx)
2340 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2341 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, getMaxLevel(cellNdx));
2344 void getReferenceParams (ReferenceParams& params, int cellNdx)
2346 params.maxLevel = getMaxLevel(cellNdx);
2350 TextureMipmapTests::TextureMipmapTests (Context& context)
2351 : TestCaseGroup(context, "mipmap", "Mipmapping tests")
2355 TextureMipmapTests::~TextureMipmapTests (void)
2359 void TextureMipmapTests::init (void)
2361 tcu::TestCaseGroup* group2D = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Mipmapping");
2362 tcu::TestCaseGroup* groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cube Map Mipmapping");
2363 tcu::TestCaseGroup* group3D = new tcu::TestCaseGroup(m_testCtx, "3d", "3D Texture Mipmapping");
2365 addChild(groupCube);
2374 { "clamp", GL_CLAMP_TO_EDGE },
2375 { "repeat", GL_REPEAT },
2376 { "mirror", GL_MIRRORED_REPEAT }
2383 } minFilterModes[] =
2385 { "nearest_nearest", GL_NEAREST_MIPMAP_NEAREST },
2386 { "linear_nearest", GL_LINEAR_MIPMAP_NEAREST },
2387 { "nearest_linear", GL_NEAREST_MIPMAP_LINEAR },
2388 { "linear_linear", GL_LINEAR_MIPMAP_LINEAR }
2398 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
2399 { COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform" },
2400 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }
2410 { "a8", GL_ALPHA, GL_UNSIGNED_BYTE },
2411 { "l8", GL_LUMINANCE, GL_UNSIGNED_BYTE },
2412 { "la88", GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
2413 { "rgb565", GL_RGB, GL_UNSIGNED_SHORT_5_6_5 },
2414 { "rgb888", GL_RGB, GL_UNSIGNED_BYTE },
2415 { "rgba4444", GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 },
2416 { "rgba5551", GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 },
2417 { "rgba8888", GL_RGBA, GL_UNSIGNED_BYTE }
2426 { "fastest", GL_FASTEST },
2427 { "nicest", GL_NICEST }
2437 { DE_NULL, 64, 64 }, // Default.
2439 { "non_square", 32, 64 }
2450 { DE_NULL, 32, 32, 32 }, // Default.
2451 { "npot", 33, 29, 27 }
2454 const int cubeMapSize = 64;
2461 } cubeCoordTypes[] =
2463 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
2464 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" },
2465 { COORDTYPE_BASIC_BIAS, "bias", "User-supplied bias value" }
2469 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
2471 tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc);
2472 group2D->addChild(coordTypeGroup);
2474 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2476 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
2478 // Add non_square variants to basic cases only.
2479 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1;
2481 for (int size = 0; size < sizeEnd; size++)
2483 std::ostringstream name;
2484 name << minFilterModes[minFilter].name
2485 << "_" << wrapModes[wrapMode].name;
2487 if (tex2DSizes[size].name)
2488 name << "_" << tex2DSizes[size].name;
2490 coordTypeGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
2491 name.str().c_str(), "",
2492 coordTypes[coordType].type,
2493 minFilterModes[minFilter].mode,
2494 wrapModes[wrapMode].mode,
2495 wrapModes[wrapMode].mode,
2496 GL_RGBA, GL_UNSIGNED_BYTE,
2497 tex2DSizes[size].width, tex2DSizes[size].height));
2503 // 2D bias variants.
2505 tcu::TestCaseGroup* biasGroup = new tcu::TestCaseGroup(m_testCtx, "bias", "User-supplied bias value");
2506 group2D->addChild(biasGroup);
2508 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2509 biasGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
2510 minFilterModes[minFilter].name, "",
2511 COORDTYPE_BASIC_BIAS,
2512 minFilterModes[minFilter].mode,
2513 GL_REPEAT, GL_REPEAT,
2514 GL_RGBA, GL_UNSIGNED_BYTE,
2515 tex2DSizes[0].width, tex2DSizes[0].height));
2518 // 2D mipmap generation variants.
2520 tcu::TestCaseGroup* genMipmapGroup = new tcu::TestCaseGroup(m_testCtx, "generate", "Mipmap generation tests");
2521 group2D->addChild(genMipmapGroup);
2523 for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); format++)
2525 for (int size = 0; size < DE_LENGTH_OF_ARRAY(tex2DSizes); size++)
2527 for (int hint = 0; hint < DE_LENGTH_OF_ARRAY(genHints); hint++)
2529 std::ostringstream name;
2530 name << formats[format].name;
2532 if (tex2DSizes[size].name)
2533 name << "_" << tex2DSizes[size].name;
2535 name << "_" << genHints[hint].name;
2537 genMipmapGroup->addChild(new Texture2DGenMipmapCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "",
2538 formats[format].format, formats[format].dataType, genHints[hint].hint,
2539 tex2DSizes[size].width, tex2DSizes[size].height));
2548 tcu::TestCaseGroup* minLodGroup = new tcu::TestCaseGroup(m_testCtx, "min_lod", "Lod control: min lod");
2549 group2D->addChild(minLodGroup);
2551 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2552 minLodGroup->addChild(new Texture2DMinLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2555 tcu::TestCaseGroup* maxLodGroup = new tcu::TestCaseGroup(m_testCtx, "max_lod", "Lod control: max lod");
2556 group2D->addChild(maxLodGroup);
2558 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2559 maxLodGroup->addChild(new Texture2DMaxLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2562 tcu::TestCaseGroup* baseLevelGroup = new tcu::TestCaseGroup(m_testCtx, "base_level", "Base level");
2563 group2D->addChild(baseLevelGroup);
2565 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2566 baseLevelGroup->addChild(new Texture2DBaseLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2569 tcu::TestCaseGroup* maxLevelGroup = new tcu::TestCaseGroup(m_testCtx, "max_level", "Max level");
2570 group2D->addChild(maxLevelGroup);
2572 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2573 maxLevelGroup->addChild(new Texture2DMaxLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2577 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
2579 tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc);
2580 groupCube->addChild(coordTypeGroup);
2582 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2584 coordTypeGroup->addChild(new TextureCubeMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
2585 minFilterModes[minFilter].name, "",
2586 cubeCoordTypes[coordType].type,
2587 minFilterModes[minFilter].mode,
2590 GL_RGBA, GL_UNSIGNED_BYTE, cubeMapSize));
2594 // Cubemap mipmap generation variants.
2596 tcu::TestCaseGroup* genMipmapGroup = new tcu::TestCaseGroup(m_testCtx, "generate", "Mipmap generation tests");
2597 groupCube->addChild(genMipmapGroup);
2599 for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); format++)
2601 for (int hint = 0; hint < DE_LENGTH_OF_ARRAY(genHints); hint++)
2603 std::ostringstream name;
2604 name << formats[format].name
2605 << "_" << genHints[hint].name;
2607 genMipmapGroup->addChild(new TextureCubeGenMipmapCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "", formats[format].format, formats[format].dataType, genHints[hint].hint, cubeMapSize));
2612 // Cubemap LOD controls.
2615 tcu::TestCaseGroup* minLodGroup = new tcu::TestCaseGroup(m_testCtx, "min_lod", "Lod control: min lod");
2616 groupCube->addChild(minLodGroup);
2618 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2619 minLodGroup->addChild(new TextureCubeMinLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2622 tcu::TestCaseGroup* maxLodGroup = new tcu::TestCaseGroup(m_testCtx, "max_lod", "Lod control: max lod");
2623 groupCube->addChild(maxLodGroup);
2625 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2626 maxLodGroup->addChild(new TextureCubeMaxLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2629 tcu::TestCaseGroup* baseLevelGroup = new tcu::TestCaseGroup(m_testCtx, "base_level", "Base level");
2630 groupCube->addChild(baseLevelGroup);
2632 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2633 baseLevelGroup->addChild(new TextureCubeBaseLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2636 tcu::TestCaseGroup* maxLevelGroup = new tcu::TestCaseGroup(m_testCtx, "max_level", "Max level");
2637 groupCube->addChild(maxLevelGroup);
2639 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2640 maxLevelGroup->addChild(new TextureCubeMaxLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2644 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
2646 tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc);
2647 group3D->addChild(coordTypeGroup);
2649 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2651 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
2653 // Add other size variants to basic cases only.
2654 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex3DSizes) : 1;
2656 for (int size = 0; size < sizeEnd; size++)
2658 std::ostringstream name;
2659 name << minFilterModes[minFilter].name
2660 << "_" << wrapModes[wrapMode].name;
2662 if (tex3DSizes[size].name)
2663 name << "_" << tex3DSizes[size].name;
2665 coordTypeGroup->addChild(new Texture3DMipmapCase(m_context,
2666 name.str().c_str(), "",
2667 coordTypes[coordType].type,
2668 minFilterModes[minFilter].mode,
2669 wrapModes[wrapMode].mode,
2670 wrapModes[wrapMode].mode,
2671 wrapModes[wrapMode].mode,
2673 tex3DSizes[size].width, tex3DSizes[size].height, tex3DSizes[size].depth));
2679 // 3D bias variants.
2681 tcu::TestCaseGroup* biasGroup = new tcu::TestCaseGroup(m_testCtx, "bias", "User-supplied bias value");
2682 group3D->addChild(biasGroup);
2684 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2685 biasGroup->addChild(new Texture3DMipmapCase(m_context,
2686 minFilterModes[minFilter].name, "",
2687 COORDTYPE_BASIC_BIAS,
2688 minFilterModes[minFilter].mode,
2689 GL_REPEAT, GL_REPEAT, GL_REPEAT,
2691 tex3DSizes[0].width, tex3DSizes[0].height, tex3DSizes[0].depth));
2697 tcu::TestCaseGroup* minLodGroup = new tcu::TestCaseGroup(m_testCtx, "min_lod", "Lod control: min lod");
2698 group3D->addChild(minLodGroup);
2700 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2701 minLodGroup->addChild(new Texture3DMinLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2704 tcu::TestCaseGroup* maxLodGroup = new tcu::TestCaseGroup(m_testCtx, "max_lod", "Lod control: max lod");
2705 group3D->addChild(maxLodGroup);
2707 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2708 maxLodGroup->addChild(new Texture3DMaxLodCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2711 tcu::TestCaseGroup* baseLevelGroup = new tcu::TestCaseGroup(m_testCtx, "base_level", "Base level");
2712 group3D->addChild(baseLevelGroup);
2714 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2715 baseLevelGroup->addChild(new Texture3DBaseLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));
2718 tcu::TestCaseGroup* maxLevelGroup = new tcu::TestCaseGroup(m_testCtx, "max_level", "Max level");
2719 group3D->addChild(maxLevelGroup);
2721 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2722 maxLevelGroup->addChild(new Texture3DMaxLevelCase(m_context, minFilterModes[minFilter].name, "", minFilterModes[minFilter].mode));