1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 2.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Mipmapping tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2fTextureMipmapTests.hpp" 25e5c31af7Sopenharmony_ci#include "glsTextureTestUtil.hpp" 26e5c31af7Sopenharmony_ci#include "gluTexture.hpp" 27e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 28e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp" 29e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 30e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 31e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 32e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 33e5c31af7Sopenharmony_ci#include "tcuMatrix.hpp" 34e5c31af7Sopenharmony_ci#include "tcuMatrixUtil.hpp" 35e5c31af7Sopenharmony_ci#include "tcuTexLookupVerifier.hpp" 36e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 37e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 38e5c31af7Sopenharmony_ci#include "deRandom.hpp" 39e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 40e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_cinamespace deqp 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_cinamespace gles2 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_cinamespace Functional 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciusing tcu::TestLog; 50e5c31af7Sopenharmony_ciusing std::vector; 51e5c31af7Sopenharmony_ciusing std::string; 52e5c31af7Sopenharmony_ciusing tcu::Sampler; 53e5c31af7Sopenharmony_ciusing tcu::Vec2; 54e5c31af7Sopenharmony_ciusing tcu::Mat2; 55e5c31af7Sopenharmony_ciusing tcu::Vec4; 56e5c31af7Sopenharmony_ciusing tcu::IVec2; 57e5c31af7Sopenharmony_ciusing tcu::IVec4; 58e5c31af7Sopenharmony_ciusing namespace glu; 59e5c31af7Sopenharmony_ciusing namespace gls::TextureTestUtil; 60e5c31af7Sopenharmony_ciusing namespace glu::TextureTestUtil; 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_cienum CoordType 63e5c31af7Sopenharmony_ci{ 64e5c31af7Sopenharmony_ci COORDTYPE_BASIC, //!< texCoord = translateScale(position). 65e5c31af7Sopenharmony_ci COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values. 66e5c31af7Sopenharmony_ci COORDTYPE_AFFINE, //!< texCoord = translateScaleRotateShear(position). 67e5c31af7Sopenharmony_ci COORDTYPE_PROJECTED, //!< Projected coordinates, w != 1 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci COORDTYPE_LAST 70e5c31af7Sopenharmony_ci}; 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci// Texture2DMipmapCase 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ciclass Texture2DMipmapCase : public tcu::TestCase 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_cipublic: 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci Texture2DMipmapCase (tcu::TestContext& testCtx, 79e5c31af7Sopenharmony_ci glu::RenderContext& renderCtx, 80e5c31af7Sopenharmony_ci const glu::ContextInfo& renderCtxInfo, 81e5c31af7Sopenharmony_ci const char* name, 82e5c31af7Sopenharmony_ci const char* desc, 83e5c31af7Sopenharmony_ci CoordType coordType, 84e5c31af7Sopenharmony_ci deUint32 minFilter, 85e5c31af7Sopenharmony_ci deUint32 wrapS, 86e5c31af7Sopenharmony_ci deUint32 wrapT, 87e5c31af7Sopenharmony_ci deUint32 format, 88e5c31af7Sopenharmony_ci deUint32 dataType, 89e5c31af7Sopenharmony_ci int width, 90e5c31af7Sopenharmony_ci int height); 91e5c31af7Sopenharmony_ci ~Texture2DMipmapCase (void); 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci void init (void); 94e5c31af7Sopenharmony_ci void deinit (void); 95e5c31af7Sopenharmony_ci IterateResult iterate (void); 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ciprivate: 98e5c31af7Sopenharmony_ci Texture2DMipmapCase (const Texture2DMipmapCase& other); 99e5c31af7Sopenharmony_ci Texture2DMipmapCase& operator= (const Texture2DMipmapCase& other); 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_ci glu::RenderContext& m_renderCtx; 102e5c31af7Sopenharmony_ci const glu::ContextInfo& m_renderCtxInfo; 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci CoordType m_coordType; 105e5c31af7Sopenharmony_ci deUint32 m_minFilter; 106e5c31af7Sopenharmony_ci deUint32 m_wrapS; 107e5c31af7Sopenharmony_ci deUint32 m_wrapT; 108e5c31af7Sopenharmony_ci deUint32 m_format; 109e5c31af7Sopenharmony_ci deUint32 m_dataType; 110e5c31af7Sopenharmony_ci int m_width; 111e5c31af7Sopenharmony_ci int m_height; 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci glu::Texture2D* m_texture; 114e5c31af7Sopenharmony_ci TextureRenderer m_renderer; 115e5c31af7Sopenharmony_ci}; 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ciTexture2DMipmapCase::Texture2DMipmapCase (tcu::TestContext& testCtx, 118e5c31af7Sopenharmony_ci glu::RenderContext& renderCtx, 119e5c31af7Sopenharmony_ci const glu::ContextInfo& renderCtxInfo, 120e5c31af7Sopenharmony_ci const char* name, 121e5c31af7Sopenharmony_ci const char* desc, 122e5c31af7Sopenharmony_ci CoordType coordType, 123e5c31af7Sopenharmony_ci deUint32 minFilter, 124e5c31af7Sopenharmony_ci deUint32 wrapS, 125e5c31af7Sopenharmony_ci deUint32 wrapT, 126e5c31af7Sopenharmony_ci deUint32 format, 127e5c31af7Sopenharmony_ci deUint32 dataType, 128e5c31af7Sopenharmony_ci int width, 129e5c31af7Sopenharmony_ci int height) 130e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 131e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 132e5c31af7Sopenharmony_ci , m_renderCtxInfo (renderCtxInfo) 133e5c31af7Sopenharmony_ci , m_coordType (coordType) 134e5c31af7Sopenharmony_ci , m_minFilter (minFilter) 135e5c31af7Sopenharmony_ci , m_wrapS (wrapS) 136e5c31af7Sopenharmony_ci , m_wrapT (wrapT) 137e5c31af7Sopenharmony_ci , m_format (format) 138e5c31af7Sopenharmony_ci , m_dataType (dataType) 139e5c31af7Sopenharmony_ci , m_width (width) 140e5c31af7Sopenharmony_ci , m_height (height) 141e5c31af7Sopenharmony_ci , m_texture (DE_NULL) 142e5c31af7Sopenharmony_ci , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, 143e5c31af7Sopenharmony_ci renderCtxInfo.isFragmentHighPrecisionSupported() ? glu::PRECISION_HIGHP // Use highp if available. 144e5c31af7Sopenharmony_ci : glu::PRECISION_MEDIUMP) 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci} 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ciTexture2DMipmapCase::~Texture2DMipmapCase (void) 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci deinit(); 151e5c31af7Sopenharmony_ci} 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_civoid Texture2DMipmapCase::init (void) 154e5c31af7Sopenharmony_ci{ 155e5c31af7Sopenharmony_ci if (!m_renderCtxInfo.isFragmentHighPrecisionSupported()) 156e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "Warning: High precision not supported in fragment shaders." << TestLog::EndMessage; 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ci if (m_coordType == COORDTYPE_PROJECTED && m_renderCtx.getRenderTarget().getNumSamples() > 0) 159e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config"); 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height); 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci int numLevels = deLog2Floor32(de::max(m_width, m_height))+1; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci // Fill texture with colored grid. 166e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 167e5c31af7Sopenharmony_ci { 168e5c31af7Sopenharmony_ci deUint32 step = 0xff / (numLevels-1); 169e5c31af7Sopenharmony_ci deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 170e5c31af7Sopenharmony_ci deUint32 dec = 0xff - inc; 171e5c31af7Sopenharmony_ci deUint32 rgb = (inc << 16) | (dec << 8) | 0xff; 172e5c31af7Sopenharmony_ci deUint32 color = 0xff000000 | rgb; 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci m_texture->getRefTexture().allocLevel(levelNdx); 175e5c31af7Sopenharmony_ci tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec()); 176e5c31af7Sopenharmony_ci } 177e5c31af7Sopenharmony_ci} 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_civoid Texture2DMipmapCase::deinit (void) 180e5c31af7Sopenharmony_ci{ 181e5c31af7Sopenharmony_ci delete m_texture; 182e5c31af7Sopenharmony_ci m_texture = DE_NULL; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci m_renderer.clear(); 185e5c31af7Sopenharmony_ci} 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_cistatic void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx) 188e5c31af7Sopenharmony_ci{ 189e5c31af7Sopenharmony_ci static const struct 190e5c31af7Sopenharmony_ci { 191e5c31af7Sopenharmony_ci Vec2 bottomLeft; 192e5c31af7Sopenharmony_ci Vec2 topRight; 193e5c31af7Sopenharmony_ci } s_basicCoords[] = 194e5c31af7Sopenharmony_ci { 195e5c31af7Sopenharmony_ci { Vec2(-0.1f, 0.1f), Vec2( 0.8f, 1.0f) }, 196e5c31af7Sopenharmony_ci { Vec2(-0.3f, -0.6f), Vec2( 0.7f, 0.4f) }, 197e5c31af7Sopenharmony_ci { Vec2(-0.3f, 0.6f), Vec2( 0.7f, -0.9f) }, 198e5c31af7Sopenharmony_ci { Vec2(-0.8f, 0.6f), Vec2( 0.7f, -0.9f) }, 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci { Vec2(-0.5f, -0.5f), Vec2( 1.5f, 1.5f) }, 201e5c31af7Sopenharmony_ci { Vec2( 1.0f, -1.0f), Vec2(-1.3f, 1.0f) }, 202e5c31af7Sopenharmony_ci { Vec2( 1.2f, -1.0f), Vec2(-1.3f, 1.6f) }, 203e5c31af7Sopenharmony_ci { Vec2( 2.2f, -1.1f), Vec2(-1.3f, 0.8f) }, 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci { Vec2(-1.5f, 1.6f), Vec2( 1.7f, -1.4f) }, 206e5c31af7Sopenharmony_ci { Vec2( 2.0f, 1.6f), Vec2( 2.3f, -1.4f) }, 207e5c31af7Sopenharmony_ci { Vec2( 1.3f, -2.6f), Vec2(-2.7f, 2.9f) }, 208e5c31af7Sopenharmony_ci { Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) }, 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci { Vec2( -8.0f, 9.0f), Vec2( 8.3f, -7.0f) }, 211e5c31af7Sopenharmony_ci { Vec2(-16.0f, 10.0f), Vec2( 18.3f, 24.0f) }, 212e5c31af7Sopenharmony_ci { Vec2( 30.2f, 55.0f), Vec2(-24.3f, -1.6f) }, 213e5c31af7Sopenharmony_ci { Vec2(-33.2f, 64.1f), Vec2( 32.1f, -64.1f) }, 214e5c31af7Sopenharmony_ci }; 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords))); 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci const Vec2& bottomLeft = s_basicCoords[cellNdx].bottomLeft; 219e5c31af7Sopenharmony_ci const Vec2& topRight = s_basicCoords[cellNdx].topRight; 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci computeQuadTexCoord2D(dst, bottomLeft, topRight); 222e5c31af7Sopenharmony_ci} 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_cistatic void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx) 225e5c31af7Sopenharmony_ci{ 226e5c31af7Sopenharmony_ci // Use basic coords as base. 227e5c31af7Sopenharmony_ci getBasicTexCoord2D(dst, cellNdx); 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci // Rotate based on cell index. 230e5c31af7Sopenharmony_ci float angle = 2.0f*DE_PI * ((float)cellNdx / 16.0f); 231e5c31af7Sopenharmony_ci tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle); 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci // Second and third row are sheared. 234e5c31af7Sopenharmony_ci float shearX = de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f; 235e5c31af7Sopenharmony_ci tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f)); 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci tcu::Mat2 transform = rotMatrix * shearMatrix; 238e5c31af7Sopenharmony_ci Vec2 p0 = transform * Vec2(dst[0], dst[1]); 239e5c31af7Sopenharmony_ci Vec2 p1 = transform * Vec2(dst[2], dst[3]); 240e5c31af7Sopenharmony_ci Vec2 p2 = transform * Vec2(dst[4], dst[5]); 241e5c31af7Sopenharmony_ci Vec2 p3 = transform * Vec2(dst[6], dst[7]); 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci dst[0] = p0.x(); dst[1] = p0.y(); 244e5c31af7Sopenharmony_ci dst[2] = p1.x(); dst[3] = p1.y(); 245e5c31af7Sopenharmony_ci dst[4] = p2.x(); dst[5] = p2.y(); 246e5c31af7Sopenharmony_ci dst[6] = p3.x(); dst[7] = p3.y(); 247e5c31af7Sopenharmony_ci} 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ciTexture2DMipmapCase::IterateResult Texture2DMipmapCase::iterate (void) 250e5c31af7Sopenharmony_ci{ 251e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci const tcu::Texture2D& refTexture = m_texture->getRefTexture(); 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ci const deUint32 magFilter = GL_NEAREST; 256e5c31af7Sopenharmony_ci const int texWidth = refTexture.getWidth(); 257e5c31af7Sopenharmony_ci const int texHeight = refTexture.getHeight(); 258e5c31af7Sopenharmony_ci const int defViewportWidth = texWidth*4; 259e5c31af7Sopenharmony_ci const int defViewportHeight = texHeight*4; 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci const RandomViewport viewport (m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName())); 262e5c31af7Sopenharmony_ci ReferenceParams sampleParams (TEXTURETYPE_2D); 263e5c31af7Sopenharmony_ci vector<float> texCoord; 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci const bool isProjected = m_coordType == COORDTYPE_PROJECTED; 266e5c31af7Sopenharmony_ci const bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS; 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci tcu::Surface renderedFrame (viewport.width, viewport.height); 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci // Viewport is divided into 4x4 grid. 271e5c31af7Sopenharmony_ci int gridWidth = 4; 272e5c31af7Sopenharmony_ci int gridHeight = 4; 273e5c31af7Sopenharmony_ci int cellWidth = viewport.width / gridWidth; 274e5c31af7Sopenharmony_ci int cellHeight = viewport.height / gridHeight; 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci // Bail out if rendertarget is too small. 277e5c31af7Sopenharmony_ci if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2) 278e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__); 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci // Sampling parameters. 281e5c31af7Sopenharmony_ci sampleParams.sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter); 282e5c31af7Sopenharmony_ci sampleParams.samplerType = glu::TextureTestUtil::getSamplerType(m_texture->getRefTexture().getFormat()); 283e5c31af7Sopenharmony_ci sampleParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0); 284e5c31af7Sopenharmony_ci sampleParams.lodMode = LODMODE_EXACT; // Use ideal lod. 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci // Upload texture data. 287e5c31af7Sopenharmony_ci m_texture->upload(); 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci // Bind gradient texture and setup sampler parameters. 290e5c31af7Sopenharmony_ci gl.bindTexture (GL_TEXTURE_2D, m_texture->getGLTexture()); 291e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS); 292e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT); 293e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter); 294e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup"); 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci // Bias values. 299e5c31af7Sopenharmony_ci static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f }; 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci // Projection values. 302e5c31af7Sopenharmony_ci static const Vec4 s_projections[] = 303e5c31af7Sopenharmony_ci { 304e5c31af7Sopenharmony_ci Vec4(1.2f, 1.0f, 0.7f, 1.0f), 305e5c31af7Sopenharmony_ci Vec4(1.3f, 0.8f, 0.6f, 2.0f), 306e5c31af7Sopenharmony_ci Vec4(0.8f, 1.0f, 1.7f, 0.6f), 307e5c31af7Sopenharmony_ci Vec4(1.2f, 1.0f, 1.7f, 1.5f) 308e5c31af7Sopenharmony_ci }; 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ci // Render cells. 311e5c31af7Sopenharmony_ci for (int gridY = 0; gridY < gridHeight; gridY++) 312e5c31af7Sopenharmony_ci { 313e5c31af7Sopenharmony_ci for (int gridX = 0; gridX < gridWidth; gridX++) 314e5c31af7Sopenharmony_ci { 315e5c31af7Sopenharmony_ci const int curX = cellWidth*gridX; 316e5c31af7Sopenharmony_ci const int curY = cellHeight*gridY; 317e5c31af7Sopenharmony_ci const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth; 318e5c31af7Sopenharmony_ci const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight; 319e5c31af7Sopenharmony_ci const int cellNdx = gridY*gridWidth + gridX; 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci // Compute texcoord. 322e5c31af7Sopenharmony_ci switch (m_coordType) 323e5c31af7Sopenharmony_ci { 324e5c31af7Sopenharmony_ci case COORDTYPE_BASIC_BIAS: // Fall-through. 325e5c31af7Sopenharmony_ci case COORDTYPE_PROJECTED: 326e5c31af7Sopenharmony_ci case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break; 327e5c31af7Sopenharmony_ci case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break; 328e5c31af7Sopenharmony_ci default: DE_ASSERT(DE_FALSE); 329e5c31af7Sopenharmony_ci } 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci if (isProjected) 332e5c31af7Sopenharmony_ci sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci if (useLodBias) 335e5c31af7Sopenharmony_ci sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci // Render with GL. 338e5c31af7Sopenharmony_ci gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH); 339e5c31af7Sopenharmony_ci m_renderer.renderQuad(0, &texCoord[0], sampleParams); 340e5c31af7Sopenharmony_ci } 341e5c31af7Sopenharmony_ci } 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci // Read result. 344e5c31af7Sopenharmony_ci glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess()); 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci // Compare and log. 347e5c31af7Sopenharmony_ci { 348e5c31af7Sopenharmony_ci const tcu::PixelFormat& pixelFormat = m_renderCtx.getRenderTarget().getPixelFormat(); 349e5c31af7Sopenharmony_ci const bool isTrilinear = m_minFilter == GL_NEAREST_MIPMAP_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_LINEAR; 350e5c31af7Sopenharmony_ci tcu::Surface referenceFrame (viewport.width, viewport.height); 351e5c31af7Sopenharmony_ci tcu::Surface errorMask (viewport.width, viewport.height); 352e5c31af7Sopenharmony_ci tcu::LookupPrecision lookupPrec; 353e5c31af7Sopenharmony_ci tcu::LodPrecision lodPrec; 354e5c31af7Sopenharmony_ci int numFailedPixels = 0; 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci lookupPrec.coordBits = tcu::IVec3(20, 20, 0); 357e5c31af7Sopenharmony_ci lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored. 358e5c31af7Sopenharmony_ci lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0))); 359e5c31af7Sopenharmony_ci lookupPrec.colorMask = getCompareMask(pixelFormat); 360e5c31af7Sopenharmony_ci lodPrec.derivateBits = 10; 361e5c31af7Sopenharmony_ci lodPrec.lodBits = isProjected ? 6 : 8; 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci for (int gridY = 0; gridY < gridHeight; gridY++) 364e5c31af7Sopenharmony_ci { 365e5c31af7Sopenharmony_ci for (int gridX = 0; gridX < gridWidth; gridX++) 366e5c31af7Sopenharmony_ci { 367e5c31af7Sopenharmony_ci const int curX = cellWidth*gridX; 368e5c31af7Sopenharmony_ci const int curY = cellHeight*gridY; 369e5c31af7Sopenharmony_ci const int curW = gridX+1 == gridWidth ? (viewport.width-curX) : cellWidth; 370e5c31af7Sopenharmony_ci const int curH = gridY+1 == gridHeight ? (viewport.height-curY) : cellHeight; 371e5c31af7Sopenharmony_ci const int cellNdx = gridY*gridWidth + gridX; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci // Compute texcoord. 374e5c31af7Sopenharmony_ci switch (m_coordType) 375e5c31af7Sopenharmony_ci { 376e5c31af7Sopenharmony_ci case COORDTYPE_BASIC_BIAS: // Fall-through. 377e5c31af7Sopenharmony_ci case COORDTYPE_PROJECTED: 378e5c31af7Sopenharmony_ci case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break; 379e5c31af7Sopenharmony_ci case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break; 380e5c31af7Sopenharmony_ci default: DE_ASSERT(DE_FALSE); 381e5c31af7Sopenharmony_ci } 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ci if (isProjected) 384e5c31af7Sopenharmony_ci sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci if (useLodBias) 387e5c31af7Sopenharmony_ci sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci // Render ideal result 390e5c31af7Sopenharmony_ci sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH), 391e5c31af7Sopenharmony_ci refTexture, &texCoord[0], sampleParams); 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci // Compare this cell 394e5c31af7Sopenharmony_ci numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 395e5c31af7Sopenharmony_ci tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 396e5c31af7Sopenharmony_ci tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 397e5c31af7Sopenharmony_ci m_texture->getRefTexture(), &texCoord[0], sampleParams, 398e5c31af7Sopenharmony_ci lookupPrec, lodPrec, m_testCtx.getWatchDog()); 399e5c31af7Sopenharmony_ci } 400e5c31af7Sopenharmony_ci } 401e5c31af7Sopenharmony_ci 402e5c31af7Sopenharmony_ci if (numFailedPixels > 0) 403e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result") 406e5c31af7Sopenharmony_ci << TestLog::Image("Rendered", "Rendered image", renderedFrame); 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci if (numFailedPixels > 0) 409e5c31af7Sopenharmony_ci { 410e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 411e5c31af7Sopenharmony_ci << TestLog::Image("ErrorMask", "Error mask", errorMask); 412e5c31af7Sopenharmony_ci } 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::EndImageSet; 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci { 417e5c31af7Sopenharmony_ci const bool isOk = numFailedPixels == 0; 418e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 419e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image verification failed"); 420e5c31af7Sopenharmony_ci } 421e5c31af7Sopenharmony_ci } 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci return STOP; 424e5c31af7Sopenharmony_ci} 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci// TextureCubeMipmapCase 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ciclass TextureCubeMipmapCase : public tcu::TestCase 429e5c31af7Sopenharmony_ci{ 430e5c31af7Sopenharmony_cipublic: 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_ci TextureCubeMipmapCase (tcu::TestContext& testCtx, 433e5c31af7Sopenharmony_ci glu::RenderContext& renderCtx, 434e5c31af7Sopenharmony_ci const glu::ContextInfo& renderCtxInfo, 435e5c31af7Sopenharmony_ci const char* name, 436e5c31af7Sopenharmony_ci const char* desc, 437e5c31af7Sopenharmony_ci CoordType coordType, 438e5c31af7Sopenharmony_ci deUint32 minFilter, 439e5c31af7Sopenharmony_ci deUint32 wrapS, 440e5c31af7Sopenharmony_ci deUint32 wrapT, 441e5c31af7Sopenharmony_ci deUint32 format, 442e5c31af7Sopenharmony_ci deUint32 dataType, 443e5c31af7Sopenharmony_ci int size); 444e5c31af7Sopenharmony_ci ~TextureCubeMipmapCase (void); 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_ci void init (void); 447e5c31af7Sopenharmony_ci void deinit (void); 448e5c31af7Sopenharmony_ci IterateResult iterate (void); 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ciprivate: 451e5c31af7Sopenharmony_ci TextureCubeMipmapCase (const TextureCubeMipmapCase& other); 452e5c31af7Sopenharmony_ci TextureCubeMipmapCase& operator= (const TextureCubeMipmapCase& other); 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_ci glu::RenderContext& m_renderCtx; 455e5c31af7Sopenharmony_ci const glu::ContextInfo& m_renderCtxInfo; 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ci CoordType m_coordType; 458e5c31af7Sopenharmony_ci deUint32 m_minFilter; 459e5c31af7Sopenharmony_ci deUint32 m_wrapS; 460e5c31af7Sopenharmony_ci deUint32 m_wrapT; 461e5c31af7Sopenharmony_ci deUint32 m_format; 462e5c31af7Sopenharmony_ci deUint32 m_dataType; 463e5c31af7Sopenharmony_ci int m_size; 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci glu::TextureCube* m_texture; 466e5c31af7Sopenharmony_ci TextureRenderer m_renderer; 467e5c31af7Sopenharmony_ci}; 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_ciTextureCubeMipmapCase::TextureCubeMipmapCase (tcu::TestContext& testCtx, 470e5c31af7Sopenharmony_ci glu::RenderContext& renderCtx, 471e5c31af7Sopenharmony_ci const glu::ContextInfo& renderCtxInfo, 472e5c31af7Sopenharmony_ci const char* name, 473e5c31af7Sopenharmony_ci const char* desc, 474e5c31af7Sopenharmony_ci CoordType coordType, 475e5c31af7Sopenharmony_ci deUint32 minFilter, 476e5c31af7Sopenharmony_ci deUint32 wrapS, 477e5c31af7Sopenharmony_ci deUint32 wrapT, 478e5c31af7Sopenharmony_ci deUint32 format, 479e5c31af7Sopenharmony_ci deUint32 dataType, 480e5c31af7Sopenharmony_ci int size) 481e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 482e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 483e5c31af7Sopenharmony_ci , m_renderCtxInfo (renderCtxInfo) 484e5c31af7Sopenharmony_ci , m_coordType (coordType) 485e5c31af7Sopenharmony_ci , m_minFilter (minFilter) 486e5c31af7Sopenharmony_ci , m_wrapS (wrapS) 487e5c31af7Sopenharmony_ci , m_wrapT (wrapT) 488e5c31af7Sopenharmony_ci , m_format (format) 489e5c31af7Sopenharmony_ci , m_dataType (dataType) 490e5c31af7Sopenharmony_ci , m_size (size) 491e5c31af7Sopenharmony_ci , m_texture (DE_NULL) 492e5c31af7Sopenharmony_ci , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, 493e5c31af7Sopenharmony_ci renderCtxInfo.isFragmentHighPrecisionSupported() ? glu::PRECISION_HIGHP // Use highp if available. 494e5c31af7Sopenharmony_ci : glu::PRECISION_MEDIUMP) 495e5c31af7Sopenharmony_ci{ 496e5c31af7Sopenharmony_ci} 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ciTextureCubeMipmapCase::~TextureCubeMipmapCase (void) 499e5c31af7Sopenharmony_ci{ 500e5c31af7Sopenharmony_ci deinit(); 501e5c31af7Sopenharmony_ci} 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_civoid TextureCubeMipmapCase::init (void) 504e5c31af7Sopenharmony_ci{ 505e5c31af7Sopenharmony_ci if (!m_renderCtxInfo.isFragmentHighPrecisionSupported()) 506e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "Warning: High precision not supported in fragment shaders." << TestLog::EndMessage; 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_ci if (m_coordType == COORDTYPE_PROJECTED && m_renderCtx.getRenderTarget().getNumSamples() > 0) 509e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Projected lookup validation not supported in multisample config"); 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci m_texture = new TextureCube(m_renderCtx, m_format, m_dataType, m_size); 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci int numLevels = deLog2Floor32(m_size)+1; 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci // Fill texture with colored grid. 516e5c31af7Sopenharmony_ci for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 517e5c31af7Sopenharmony_ci { 518e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci deUint32 step = 0xff / (numLevels-1); 521e5c31af7Sopenharmony_ci deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 522e5c31af7Sopenharmony_ci deUint32 dec = 0xff - inc; 523e5c31af7Sopenharmony_ci deUint32 rgb = 0; 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci switch (faceNdx) 526e5c31af7Sopenharmony_ci { 527e5c31af7Sopenharmony_ci case 0: rgb = (inc << 16) | (dec << 8) | 255; break; 528e5c31af7Sopenharmony_ci case 1: rgb = (255 << 16) | (inc << 8) | dec; break; 529e5c31af7Sopenharmony_ci case 2: rgb = (dec << 16) | (255 << 8) | inc; break; 530e5c31af7Sopenharmony_ci case 3: rgb = (dec << 16) | (inc << 8) | 255; break; 531e5c31af7Sopenharmony_ci case 4: rgb = (255 << 16) | (dec << 8) | inc; break; 532e5c31af7Sopenharmony_ci case 5: rgb = (inc << 16) | (255 << 8) | dec; break; 533e5c31af7Sopenharmony_ci } 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci deUint32 color = 0xff000000 | rgb; 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_ci m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx); 538e5c31af7Sopenharmony_ci tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec()); 539e5c31af7Sopenharmony_ci } 540e5c31af7Sopenharmony_ci } 541e5c31af7Sopenharmony_ci} 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_civoid TextureCubeMipmapCase::deinit (void) 544e5c31af7Sopenharmony_ci{ 545e5c31af7Sopenharmony_ci delete m_texture; 546e5c31af7Sopenharmony_ci m_texture = DE_NULL; 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci m_renderer.clear(); 549e5c31af7Sopenharmony_ci} 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_cistatic void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height) 552e5c31af7Sopenharmony_ci{ 553e5c31af7Sopenharmony_ci const int minWidth = 8; 554e5c31af7Sopenharmony_ci const int minHeight = 8; 555e5c31af7Sopenharmony_ci 556e5c31af7Sopenharmony_ci bool partition = rnd.getFloat() > 0.4f; 557e5c31af7Sopenharmony_ci bool partitionX = partition && width > minWidth && rnd.getBool(); 558e5c31af7Sopenharmony_ci bool partitionY = partition && height > minHeight && !partitionX; 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci if (partitionX) 561e5c31af7Sopenharmony_ci { 562e5c31af7Sopenharmony_ci int split = width/2 + rnd.getInt(-width/4, +width/4); 563e5c31af7Sopenharmony_ci randomPartition(dst, rnd, x, y, split, height); 564e5c31af7Sopenharmony_ci randomPartition(dst, rnd, x+split, y, width-split, height); 565e5c31af7Sopenharmony_ci } 566e5c31af7Sopenharmony_ci else if (partitionY) 567e5c31af7Sopenharmony_ci { 568e5c31af7Sopenharmony_ci int split = height/2 + rnd.getInt(-height/4, +height/4); 569e5c31af7Sopenharmony_ci randomPartition(dst, rnd, x, y, width, split); 570e5c31af7Sopenharmony_ci randomPartition(dst, rnd, x, y+split, width, height-split); 571e5c31af7Sopenharmony_ci } 572e5c31af7Sopenharmony_ci else 573e5c31af7Sopenharmony_ci dst.push_back(IVec4(x, y, width, height)); 574e5c31af7Sopenharmony_ci} 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_cistatic void computeGridLayout (vector<IVec4>& dst, int width, int height) 577e5c31af7Sopenharmony_ci{ 578e5c31af7Sopenharmony_ci de::Random rnd(7); 579e5c31af7Sopenharmony_ci randomPartition(dst, rnd, 0, 0, width, height); 580e5c31af7Sopenharmony_ci} 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ciTextureCubeMipmapCase::IterateResult TextureCubeMipmapCase::iterate (void) 583e5c31af7Sopenharmony_ci{ 584e5c31af7Sopenharmony_ci const deUint32 magFilter = GL_NEAREST; 585e5c31af7Sopenharmony_ci const int texWidth = m_texture->getRefTexture().getSize(); 586e5c31af7Sopenharmony_ci const int texHeight = m_texture->getRefTexture().getSize(); 587e5c31af7Sopenharmony_ci const int defViewportWidth = texWidth*2; 588e5c31af7Sopenharmony_ci const int defViewportHeight = texHeight*2; 589e5c31af7Sopenharmony_ci 590e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 591e5c31af7Sopenharmony_ci const RandomViewport viewport (m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName())); 592e5c31af7Sopenharmony_ci 593e5c31af7Sopenharmony_ci const bool isProjected = m_coordType == COORDTYPE_PROJECTED; 594e5c31af7Sopenharmony_ci const bool useLodBias = m_coordType == COORDTYPE_BASIC_BIAS; 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci vector<float> texCoord; 597e5c31af7Sopenharmony_ci tcu::Surface renderedFrame (viewport.width, viewport.height); 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ci // Bail out if rendertarget is too small. 600e5c31af7Sopenharmony_ci if (viewport.width < defViewportWidth/2 || viewport.height < defViewportHeight/2) 601e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__); 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci bool isES3Compatible = m_renderCtxInfo.isES3Compatible(); 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_ci // Upload texture data. 606e5c31af7Sopenharmony_ci m_texture->upload(); 607e5c31af7Sopenharmony_ci 608e5c31af7Sopenharmony_ci // Bind gradient texture and setup sampler parameters. 609e5c31af7Sopenharmony_ci gl.bindTexture (GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture()); 610e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS); 611e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT); 612e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter); 613e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter); 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup"); 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci // Compute grid. 618e5c31af7Sopenharmony_ci vector<IVec4> gridLayout; 619e5c31af7Sopenharmony_ci computeGridLayout(gridLayout, viewport.width, viewport.height); 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci // Bias values. 622e5c31af7Sopenharmony_ci static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f }; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci // Projection values \note Less agressive than in 2D case due to smaller quads. 625e5c31af7Sopenharmony_ci static const Vec4 s_projections[] = 626e5c31af7Sopenharmony_ci { 627e5c31af7Sopenharmony_ci Vec4(1.2f, 1.0f, 0.7f, 1.0f), 628e5c31af7Sopenharmony_ci Vec4(1.3f, 0.8f, 0.6f, 1.1f), 629e5c31af7Sopenharmony_ci Vec4(0.8f, 1.0f, 1.2f, 0.8f), 630e5c31af7Sopenharmony_ci Vec4(1.2f, 1.0f, 1.3f, 0.9f) 631e5c31af7Sopenharmony_ci }; 632e5c31af7Sopenharmony_ci 633e5c31af7Sopenharmony_ci // Render with GL 634e5c31af7Sopenharmony_ci for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++) 635e5c31af7Sopenharmony_ci { 636e5c31af7Sopenharmony_ci const int curX = gridLayout[cellNdx].x(); 637e5c31af7Sopenharmony_ci const int curY = gridLayout[cellNdx].y(); 638e5c31af7Sopenharmony_ci const int curW = gridLayout[cellNdx].z(); 639e5c31af7Sopenharmony_ci const int curH = gridLayout[cellNdx].w(); 640e5c31af7Sopenharmony_ci const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST); 641e5c31af7Sopenharmony_ci RenderParams params (TEXTURETYPE_CUBE); 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported. 644e5c31af7Sopenharmony_ci computeQuadTexCoordCube(texCoord, cubeFace); 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci if (isProjected) 647e5c31af7Sopenharmony_ci { 648e5c31af7Sopenharmony_ci params.flags |= ReferenceParams::PROJECTED; 649e5c31af7Sopenharmony_ci params.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 650e5c31af7Sopenharmony_ci } 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ci if (useLodBias) 653e5c31af7Sopenharmony_ci { 654e5c31af7Sopenharmony_ci params.flags |= ReferenceParams::USE_BIAS; 655e5c31af7Sopenharmony_ci params.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 656e5c31af7Sopenharmony_ci } 657e5c31af7Sopenharmony_ci 658e5c31af7Sopenharmony_ci // Render with GL. 659e5c31af7Sopenharmony_ci gl.viewport(viewport.x+curX, viewport.y+curY, curW, curH); 660e5c31af7Sopenharmony_ci m_renderer.renderQuad(0, &texCoord[0], params); 661e5c31af7Sopenharmony_ci } 662e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Draw"); 663e5c31af7Sopenharmony_ci 664e5c31af7Sopenharmony_ci // Read result. 665e5c31af7Sopenharmony_ci glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess()); 666e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels"); 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_ci // Render reference and compare 669e5c31af7Sopenharmony_ci { 670e5c31af7Sopenharmony_ci tcu::Surface referenceFrame (viewport.width, viewport.height); 671e5c31af7Sopenharmony_ci tcu::Surface errorMask (viewport.width, viewport.height); 672e5c31af7Sopenharmony_ci int numFailedPixels = 0; 673e5c31af7Sopenharmony_ci ReferenceParams params (TEXTURETYPE_CUBE); 674e5c31af7Sopenharmony_ci tcu::LookupPrecision lookupPrec; 675e5c31af7Sopenharmony_ci tcu::LodPrecision lodPrec; 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_ci // Params for rendering reference 678e5c31af7Sopenharmony_ci params.sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter); 679e5c31af7Sopenharmony_ci params.sampler.seamlessCubeMap = isES3Compatible; 680e5c31af7Sopenharmony_ci params.lodMode = LODMODE_EXACT; 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci // Comparison parameters 683e5c31af7Sopenharmony_ci lookupPrec.colorMask = getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat()); 684e5c31af7Sopenharmony_ci lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0))); 685e5c31af7Sopenharmony_ci lookupPrec.coordBits = isProjected ? tcu::IVec3(8) : tcu::IVec3(10); 686e5c31af7Sopenharmony_ci lookupPrec.uvwBits = tcu::IVec3(5,5,0); 687e5c31af7Sopenharmony_ci lodPrec.derivateBits = 10; 688e5c31af7Sopenharmony_ci lodPrec.lodBits = isES3Compatible ? 3 : 4; 689e5c31af7Sopenharmony_ci lodPrec.lodBits = isProjected ? lodPrec.lodBits : 6; 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++) 692e5c31af7Sopenharmony_ci { 693e5c31af7Sopenharmony_ci const int curX = gridLayout[cellNdx].x(); 694e5c31af7Sopenharmony_ci const int curY = gridLayout[cellNdx].y(); 695e5c31af7Sopenharmony_ci const int curW = gridLayout[cellNdx].z(); 696e5c31af7Sopenharmony_ci const int curH = gridLayout[cellNdx].w(); 697e5c31af7Sopenharmony_ci const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST); 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported. 700e5c31af7Sopenharmony_ci computeQuadTexCoordCube(texCoord, cubeFace); 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci if (isProjected) 703e5c31af7Sopenharmony_ci { 704e5c31af7Sopenharmony_ci params.flags |= ReferenceParams::PROJECTED; 705e5c31af7Sopenharmony_ci params.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 706e5c31af7Sopenharmony_ci } 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci if (useLodBias) 709e5c31af7Sopenharmony_ci { 710e5c31af7Sopenharmony_ci params.flags |= ReferenceParams::USE_BIAS; 711e5c31af7Sopenharmony_ci params.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 712e5c31af7Sopenharmony_ci } 713e5c31af7Sopenharmony_ci 714e5c31af7Sopenharmony_ci // Render ideal reference. 715e5c31af7Sopenharmony_ci { 716e5c31af7Sopenharmony_ci tcu::SurfaceAccess idealDst(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY, curW, curH); 717e5c31af7Sopenharmony_ci sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params); 718e5c31af7Sopenharmony_ci } 719e5c31af7Sopenharmony_ci 720e5c31af7Sopenharmony_ci // Compare this cell 721e5c31af7Sopenharmony_ci numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 722e5c31af7Sopenharmony_ci tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 723e5c31af7Sopenharmony_ci tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 724e5c31af7Sopenharmony_ci m_texture->getRefTexture(), &texCoord[0], params, 725e5c31af7Sopenharmony_ci lookupPrec, lodPrec, m_testCtx.getWatchDog()); 726e5c31af7Sopenharmony_ci } 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci if (numFailedPixels > 0) 729e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::ImageSet("Result", "Verification result") 732e5c31af7Sopenharmony_ci << TestLog::Image("Rendered", "Rendered image", renderedFrame); 733e5c31af7Sopenharmony_ci 734e5c31af7Sopenharmony_ci if (numFailedPixels > 0) 735e5c31af7Sopenharmony_ci { 736e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 737e5c31af7Sopenharmony_ci << TestLog::Image("ErrorMask", "Error mask", errorMask); 738e5c31af7Sopenharmony_ci } 739e5c31af7Sopenharmony_ci 740e5c31af7Sopenharmony_ci m_testCtx.getLog() << TestLog::EndImageSet; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci { 743e5c31af7Sopenharmony_ci const bool isOk = numFailedPixels == 0; 744e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 745e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image verification failed"); 746e5c31af7Sopenharmony_ci } 747e5c31af7Sopenharmony_ci } 748e5c31af7Sopenharmony_ci 749e5c31af7Sopenharmony_ci return STOP; 750e5c31af7Sopenharmony_ci} 751e5c31af7Sopenharmony_ci 752e5c31af7Sopenharmony_ci// Texture2DGenMipmapCase 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ciclass Texture2DGenMipmapCase : public tcu::TestCase 755e5c31af7Sopenharmony_ci{ 756e5c31af7Sopenharmony_cipublic: 757e5c31af7Sopenharmony_ci 758e5c31af7Sopenharmony_ci Texture2DGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int width, int height); 759e5c31af7Sopenharmony_ci ~Texture2DGenMipmapCase (void); 760e5c31af7Sopenharmony_ci 761e5c31af7Sopenharmony_ci void init (void); 762e5c31af7Sopenharmony_ci void deinit (void); 763e5c31af7Sopenharmony_ci IterateResult iterate (void); 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ciprivate: 766e5c31af7Sopenharmony_ci Texture2DGenMipmapCase (const Texture2DGenMipmapCase& other); 767e5c31af7Sopenharmony_ci Texture2DGenMipmapCase& operator= (const Texture2DGenMipmapCase& other); 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci glu::RenderContext& m_renderCtx; 770e5c31af7Sopenharmony_ci 771e5c31af7Sopenharmony_ci deUint32 m_format; 772e5c31af7Sopenharmony_ci deUint32 m_dataType; 773e5c31af7Sopenharmony_ci deUint32 m_hint; 774e5c31af7Sopenharmony_ci int m_width; 775e5c31af7Sopenharmony_ci int m_height; 776e5c31af7Sopenharmony_ci 777e5c31af7Sopenharmony_ci glu::Texture2D* m_texture; 778e5c31af7Sopenharmony_ci TextureRenderer m_renderer; 779e5c31af7Sopenharmony_ci}; 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ciTexture2DGenMipmapCase::Texture2DGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int width, int height) 782e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 783e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 784e5c31af7Sopenharmony_ci , m_format (format) 785e5c31af7Sopenharmony_ci , m_dataType (dataType) 786e5c31af7Sopenharmony_ci , m_hint (hint) 787e5c31af7Sopenharmony_ci , m_width (width) 788e5c31af7Sopenharmony_ci , m_height (height) 789e5c31af7Sopenharmony_ci , m_texture (DE_NULL) 790e5c31af7Sopenharmony_ci , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP) 791e5c31af7Sopenharmony_ci{ 792e5c31af7Sopenharmony_ci} 793e5c31af7Sopenharmony_ci 794e5c31af7Sopenharmony_ciTexture2DGenMipmapCase::~Texture2DGenMipmapCase (void) 795e5c31af7Sopenharmony_ci{ 796e5c31af7Sopenharmony_ci deinit(); 797e5c31af7Sopenharmony_ci} 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_civoid Texture2DGenMipmapCase::init (void) 800e5c31af7Sopenharmony_ci{ 801e5c31af7Sopenharmony_ci DE_ASSERT(!m_texture); 802e5c31af7Sopenharmony_ci m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height); 803e5c31af7Sopenharmony_ci} 804e5c31af7Sopenharmony_ci 805e5c31af7Sopenharmony_civoid Texture2DGenMipmapCase::deinit (void) 806e5c31af7Sopenharmony_ci{ 807e5c31af7Sopenharmony_ci delete m_texture; 808e5c31af7Sopenharmony_ci m_texture = DE_NULL; 809e5c31af7Sopenharmony_ci 810e5c31af7Sopenharmony_ci m_renderer.clear(); 811e5c31af7Sopenharmony_ci} 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_ciTexture2DGenMipmapCase::IterateResult Texture2DGenMipmapCase::iterate (void) 814e5c31af7Sopenharmony_ci{ 815e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci const deUint32 minFilter = GL_NEAREST_MIPMAP_NEAREST; 818e5c31af7Sopenharmony_ci const deUint32 magFilter = GL_NEAREST; 819e5c31af7Sopenharmony_ci const deUint32 wrapS = GL_CLAMP_TO_EDGE; 820e5c31af7Sopenharmony_ci const deUint32 wrapT = GL_CLAMP_TO_EDGE; 821e5c31af7Sopenharmony_ci 822e5c31af7Sopenharmony_ci const int numLevels = deLog2Floor32(de::max(m_width, m_height))+1; 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci tcu::Texture2D resultTexture (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), isES2Context(m_renderCtx.getType())); 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci vector<float> texCoord; 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci // Initialize texture level 0 with colored grid. 829e5c31af7Sopenharmony_ci m_texture->getRefTexture().allocLevel(0); 830e5c31af7Sopenharmony_ci 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)); 831e5c31af7Sopenharmony_ci 832e5c31af7Sopenharmony_ci // Upload data and setup params. 833e5c31af7Sopenharmony_ci m_texture->upload(); 834e5c31af7Sopenharmony_ci 835e5c31af7Sopenharmony_ci gl.bindTexture (GL_TEXTURE_2D, m_texture->getGLTexture()); 836e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); 837e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); 838e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); 839e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); 840e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup"); 841e5c31af7Sopenharmony_ci 842e5c31af7Sopenharmony_ci // Generate mipmap. 843e5c31af7Sopenharmony_ci gl.hint(GL_GENERATE_MIPMAP_HINT, m_hint); 844e5c31af7Sopenharmony_ci gl.generateMipmap(GL_TEXTURE_2D); 845e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap()"); 846e5c31af7Sopenharmony_ci 847e5c31af7Sopenharmony_ci // Use (0, 0) -> (1, 1) texture coordinates. 848e5c31af7Sopenharmony_ci computeQuadTexCoord2D(texCoord, Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f)); 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci // Fetch resulting texture by rendering. 851e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 852e5c31af7Sopenharmony_ci { 853e5c31af7Sopenharmony_ci const int levelWidth = de::max(1, m_width >> levelNdx); 854e5c31af7Sopenharmony_ci const int levelHeight = de::max(1, m_height >> levelNdx); 855e5c31af7Sopenharmony_ci const RandomViewport viewport (m_renderCtx.getRenderTarget(), levelWidth, levelHeight, deStringHash(getName()) + levelNdx); 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_ci gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); 858e5c31af7Sopenharmony_ci m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D); 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_ci resultTexture.allocLevel(levelNdx); 861e5c31af7Sopenharmony_ci glu::readPixels(m_renderCtx, viewport.x, viewport.y, resultTexture.getLevel(levelNdx)); 862e5c31af7Sopenharmony_ci } 863e5c31af7Sopenharmony_ci 864e5c31af7Sopenharmony_ci // Compare results 865e5c31af7Sopenharmony_ci { 866e5c31af7Sopenharmony_ci 867e5c31af7Sopenharmony_ci const IVec4 framebufferBits = max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0)); 868e5c31af7Sopenharmony_ci const IVec4 formatBits = tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType)); 869e5c31af7Sopenharmony_ci const tcu::BVec4 formatMask = greaterThan(formatBits, IVec4(0)); 870e5c31af7Sopenharmony_ci const IVec4 cmpBits = select(min(framebufferBits, formatBits), framebufferBits, formatMask); 871e5c31af7Sopenharmony_ci GenMipmapPrecision comparePrec; 872e5c31af7Sopenharmony_ci 873e5c31af7Sopenharmony_ci comparePrec.colorMask = getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat()); 874e5c31af7Sopenharmony_ci comparePrec.colorThreshold = tcu::computeFixedPointThreshold(cmpBits); 875e5c31af7Sopenharmony_ci comparePrec.filterBits = tcu::IVec3(4, 4, 0); 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci const qpTestResult compareResult = compareGenMipmapResult(m_testCtx.getLog(), resultTexture, m_texture->getRefTexture(), comparePrec); 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci m_testCtx.setTestResult(compareResult, compareResult == QP_TEST_RESULT_PASS ? "Pass" : 880e5c31af7Sopenharmony_ci compareResult == QP_TEST_RESULT_QUALITY_WARNING ? "Low-quality method used" : 881e5c31af7Sopenharmony_ci compareResult == QP_TEST_RESULT_FAIL ? "Image comparison failed" : ""); 882e5c31af7Sopenharmony_ci } 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_ci return STOP; 885e5c31af7Sopenharmony_ci} 886e5c31af7Sopenharmony_ci 887e5c31af7Sopenharmony_ci// TextureCubeGenMipmapCase 888e5c31af7Sopenharmony_ci 889e5c31af7Sopenharmony_ciclass TextureCubeGenMipmapCase : public tcu::TestCase 890e5c31af7Sopenharmony_ci{ 891e5c31af7Sopenharmony_cipublic: 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci TextureCubeGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int size); 894e5c31af7Sopenharmony_ci ~TextureCubeGenMipmapCase (void); 895e5c31af7Sopenharmony_ci 896e5c31af7Sopenharmony_ci void init (void); 897e5c31af7Sopenharmony_ci void deinit (void); 898e5c31af7Sopenharmony_ci IterateResult iterate (void); 899e5c31af7Sopenharmony_ci 900e5c31af7Sopenharmony_ciprivate: 901e5c31af7Sopenharmony_ci TextureCubeGenMipmapCase (const TextureCubeGenMipmapCase& other); 902e5c31af7Sopenharmony_ci TextureCubeGenMipmapCase& operator= (const TextureCubeGenMipmapCase& other); 903e5c31af7Sopenharmony_ci 904e5c31af7Sopenharmony_ci glu::RenderContext& m_renderCtx; 905e5c31af7Sopenharmony_ci 906e5c31af7Sopenharmony_ci deUint32 m_format; 907e5c31af7Sopenharmony_ci deUint32 m_dataType; 908e5c31af7Sopenharmony_ci deUint32 m_hint; 909e5c31af7Sopenharmony_ci int m_size; 910e5c31af7Sopenharmony_ci 911e5c31af7Sopenharmony_ci glu::TextureCube* m_texture; 912e5c31af7Sopenharmony_ci TextureRenderer m_renderer; 913e5c31af7Sopenharmony_ci}; 914e5c31af7Sopenharmony_ci 915e5c31af7Sopenharmony_ciTextureCubeGenMipmapCase::TextureCubeGenMipmapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 hint, int size) 916e5c31af7Sopenharmony_ci : TestCase (testCtx, name, desc) 917e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 918e5c31af7Sopenharmony_ci , m_format (format) 919e5c31af7Sopenharmony_ci , m_dataType (dataType) 920e5c31af7Sopenharmony_ci , m_hint (hint) 921e5c31af7Sopenharmony_ci , m_size (size) 922e5c31af7Sopenharmony_ci , m_texture (DE_NULL) 923e5c31af7Sopenharmony_ci , m_renderer (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP) 924e5c31af7Sopenharmony_ci{ 925e5c31af7Sopenharmony_ci} 926e5c31af7Sopenharmony_ci 927e5c31af7Sopenharmony_ciTextureCubeGenMipmapCase::~TextureCubeGenMipmapCase (void) 928e5c31af7Sopenharmony_ci{ 929e5c31af7Sopenharmony_ci deinit(); 930e5c31af7Sopenharmony_ci} 931e5c31af7Sopenharmony_ci 932e5c31af7Sopenharmony_civoid TextureCubeGenMipmapCase::init (void) 933e5c31af7Sopenharmony_ci{ 934e5c31af7Sopenharmony_ci if (m_renderCtx.getRenderTarget().getWidth() < 3*m_size || m_renderCtx.getRenderTarget().getHeight() < 2*m_size) 935e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Render target size must be at least (" + de::toString(3*m_size) + ", " + de::toString(2*m_size) + ")"); 936e5c31af7Sopenharmony_ci 937e5c31af7Sopenharmony_ci DE_ASSERT(!m_texture); 938e5c31af7Sopenharmony_ci m_texture = new TextureCube(m_renderCtx, m_format, m_dataType, m_size); 939e5c31af7Sopenharmony_ci} 940e5c31af7Sopenharmony_ci 941e5c31af7Sopenharmony_civoid TextureCubeGenMipmapCase::deinit (void) 942e5c31af7Sopenharmony_ci{ 943e5c31af7Sopenharmony_ci delete m_texture; 944e5c31af7Sopenharmony_ci m_texture = DE_NULL; 945e5c31af7Sopenharmony_ci 946e5c31af7Sopenharmony_ci m_renderer.clear(); 947e5c31af7Sopenharmony_ci} 948e5c31af7Sopenharmony_ci 949e5c31af7Sopenharmony_ciTextureCubeGenMipmapCase::IterateResult TextureCubeGenMipmapCase::iterate (void) 950e5c31af7Sopenharmony_ci{ 951e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 952e5c31af7Sopenharmony_ci 953e5c31af7Sopenharmony_ci const deUint32 minFilter = GL_NEAREST_MIPMAP_NEAREST; 954e5c31af7Sopenharmony_ci const deUint32 magFilter = GL_NEAREST; 955e5c31af7Sopenharmony_ci const deUint32 wrapS = GL_CLAMP_TO_EDGE; 956e5c31af7Sopenharmony_ci const deUint32 wrapT = GL_CLAMP_TO_EDGE; 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci tcu::TextureCube resultTexture (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), m_size); 959e5c31af7Sopenharmony_ci 960e5c31af7Sopenharmony_ci const int numLevels = deLog2Floor32(m_size)+1; 961e5c31af7Sopenharmony_ci vector<float> texCoord; 962e5c31af7Sopenharmony_ci 963e5c31af7Sopenharmony_ci // Initialize texture level 0 with colored grid. 964e5c31af7Sopenharmony_ci for (int face = 0; face < tcu::CUBEFACE_LAST; face++) 965e5c31af7Sopenharmony_ci { 966e5c31af7Sopenharmony_ci Vec4 ca, cb; // Grid colors. 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ci switch (face) 969e5c31af7Sopenharmony_ci { 970e5c31af7Sopenharmony_ci case 0: ca = Vec4(1.0f, 0.3f, 0.0f, 0.7f); cb = Vec4(0.0f, 0.0f, 1.0f, 1.0f); break; 971e5c31af7Sopenharmony_ci case 1: ca = Vec4(0.0f, 1.0f, 0.5f, 0.5f); cb = Vec4(1.0f, 0.0f, 0.0f, 1.0f); break; 972e5c31af7Sopenharmony_ci case 2: ca = Vec4(0.7f, 0.0f, 1.0f, 0.3f); cb = Vec4(0.0f, 1.0f, 0.0f, 1.0f); break; 973e5c31af7Sopenharmony_ci case 3: ca = Vec4(0.0f, 0.3f, 1.0f, 1.0f); cb = Vec4(1.0f, 0.0f, 0.0f, 0.7f); break; 974e5c31af7Sopenharmony_ci case 4: ca = Vec4(1.0f, 0.0f, 0.5f, 1.0f); cb = Vec4(0.0f, 1.0f, 0.0f, 0.5f); break; 975e5c31af7Sopenharmony_ci case 5: ca = Vec4(0.7f, 1.0f, 0.0f, 1.0f); cb = Vec4(0.0f, 0.0f, 1.0f, 0.3f); break; 976e5c31af7Sopenharmony_ci } 977e5c31af7Sopenharmony_ci 978e5c31af7Sopenharmony_ci m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0); 979e5c31af7Sopenharmony_ci fillWithGrid(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), 8, ca, cb); 980e5c31af7Sopenharmony_ci } 981e5c31af7Sopenharmony_ci 982e5c31af7Sopenharmony_ci // Upload data and setup params. 983e5c31af7Sopenharmony_ci m_texture->upload(); 984e5c31af7Sopenharmony_ci 985e5c31af7Sopenharmony_ci gl.bindTexture (GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture()); 986e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrapS); 987e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrapT); 988e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, minFilter); 989e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter); 990e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup"); 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci // Generate mipmap. 993e5c31af7Sopenharmony_ci gl.hint(GL_GENERATE_MIPMAP_HINT, m_hint); 994e5c31af7Sopenharmony_ci gl.generateMipmap(GL_TEXTURE_CUBE_MAP); 995e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap()"); 996e5c31af7Sopenharmony_ci 997e5c31af7Sopenharmony_ci // Render all levels. 998e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 999e5c31af7Sopenharmony_ci { 1000e5c31af7Sopenharmony_ci const int levelWidth = de::max(1, m_size >> levelNdx); 1001e5c31af7Sopenharmony_ci const int levelHeight = de::max(1, m_size >> levelNdx); 1002e5c31af7Sopenharmony_ci 1003e5c31af7Sopenharmony_ci for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 1004e5c31af7Sopenharmony_ci { 1005e5c31af7Sopenharmony_ci const RandomViewport viewport (m_renderCtx.getRenderTarget(), levelWidth*3, levelHeight*2, deStringHash(getName()) ^ deInt32Hash(levelNdx + faceNdx)); 1006e5c31af7Sopenharmony_ci const tcu::CubeFace face = tcu::CubeFace(faceNdx); 1007e5c31af7Sopenharmony_ci 1008e5c31af7Sopenharmony_ci computeQuadTexCoordCube(texCoord, face); 1009e5c31af7Sopenharmony_ci 1010e5c31af7Sopenharmony_ci gl.viewport(viewport.x, viewport.y, levelWidth, levelHeight); 1011e5c31af7Sopenharmony_ci m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE); 1012e5c31af7Sopenharmony_ci 1013e5c31af7Sopenharmony_ci resultTexture.allocLevel(face, levelNdx); 1014e5c31af7Sopenharmony_ci glu::readPixels(m_renderCtx, viewport.x, viewport.y, resultTexture.getLevelFace(levelNdx, face)); 1015e5c31af7Sopenharmony_ci } 1016e5c31af7Sopenharmony_ci } 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_ci // Compare results 1019e5c31af7Sopenharmony_ci { 1020e5c31af7Sopenharmony_ci const IVec4 framebufferBits = max(getBitsVec(m_renderCtx.getRenderTarget().getPixelFormat())-2, IVec4(0)); 1021e5c31af7Sopenharmony_ci const IVec4 formatBits = tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType)); 1022e5c31af7Sopenharmony_ci const tcu::BVec4 formatMask = greaterThan(formatBits, IVec4(0)); 1023e5c31af7Sopenharmony_ci const IVec4 cmpBits = select(min(framebufferBits, formatBits), framebufferBits, formatMask); 1024e5c31af7Sopenharmony_ci GenMipmapPrecision comparePrec; 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ci comparePrec.colorMask = getCompareMask(m_renderCtx.getRenderTarget().getPixelFormat()); 1027e5c31af7Sopenharmony_ci comparePrec.colorThreshold = tcu::computeFixedPointThreshold(cmpBits); 1028e5c31af7Sopenharmony_ci comparePrec.filterBits = tcu::IVec3(4, 4, 0); 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_ci const qpTestResult compareResult = compareGenMipmapResult(m_testCtx.getLog(), resultTexture, m_texture->getRefTexture(), comparePrec); 1031e5c31af7Sopenharmony_ci 1032e5c31af7Sopenharmony_ci m_testCtx.setTestResult(compareResult, compareResult == QP_TEST_RESULT_PASS ? "Pass" : 1033e5c31af7Sopenharmony_ci compareResult == QP_TEST_RESULT_QUALITY_WARNING ? "Low-quality method used" : 1034e5c31af7Sopenharmony_ci compareResult == QP_TEST_RESULT_FAIL ? "Image comparison failed" : ""); 1035e5c31af7Sopenharmony_ci } 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_ci return STOP; 1038e5c31af7Sopenharmony_ci} 1039e5c31af7Sopenharmony_ci 1040e5c31af7Sopenharmony_ciTextureMipmapTests::TextureMipmapTests (Context& context) 1041e5c31af7Sopenharmony_ci : TestCaseGroup(context, "mipmap", "Mipmapping tests") 1042e5c31af7Sopenharmony_ci{ 1043e5c31af7Sopenharmony_ci} 1044e5c31af7Sopenharmony_ci 1045e5c31af7Sopenharmony_ciTextureMipmapTests::~TextureMipmapTests (void) 1046e5c31af7Sopenharmony_ci{ 1047e5c31af7Sopenharmony_ci} 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_civoid TextureMipmapTests::init (void) 1050e5c31af7Sopenharmony_ci{ 1051e5c31af7Sopenharmony_ci tcu::TestCaseGroup* group2D = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Mipmapping"); 1052e5c31af7Sopenharmony_ci tcu::TestCaseGroup* groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cube Map Filtering"); 1053e5c31af7Sopenharmony_ci addChild(group2D); 1054e5c31af7Sopenharmony_ci addChild(groupCube); 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci static const struct 1057e5c31af7Sopenharmony_ci { 1058e5c31af7Sopenharmony_ci const char* name; 1059e5c31af7Sopenharmony_ci deUint32 mode; 1060e5c31af7Sopenharmony_ci } wrapModes[] = 1061e5c31af7Sopenharmony_ci { 1062e5c31af7Sopenharmony_ci { "clamp", GL_CLAMP_TO_EDGE }, 1063e5c31af7Sopenharmony_ci { "repeat", GL_REPEAT }, 1064e5c31af7Sopenharmony_ci { "mirror", GL_MIRRORED_REPEAT } 1065e5c31af7Sopenharmony_ci }; 1066e5c31af7Sopenharmony_ci 1067e5c31af7Sopenharmony_ci static const struct 1068e5c31af7Sopenharmony_ci { 1069e5c31af7Sopenharmony_ci const char* name; 1070e5c31af7Sopenharmony_ci deUint32 mode; 1071e5c31af7Sopenharmony_ci } minFilterModes[] = 1072e5c31af7Sopenharmony_ci { 1073e5c31af7Sopenharmony_ci { "nearest_nearest", GL_NEAREST_MIPMAP_NEAREST }, 1074e5c31af7Sopenharmony_ci { "linear_nearest", GL_LINEAR_MIPMAP_NEAREST }, 1075e5c31af7Sopenharmony_ci { "nearest_linear", GL_NEAREST_MIPMAP_LINEAR }, 1076e5c31af7Sopenharmony_ci { "linear_linear", GL_LINEAR_MIPMAP_LINEAR } 1077e5c31af7Sopenharmony_ci }; 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_ci static const struct 1080e5c31af7Sopenharmony_ci { 1081e5c31af7Sopenharmony_ci CoordType type; 1082e5c31af7Sopenharmony_ci const char* name; 1083e5c31af7Sopenharmony_ci const char* desc; 1084e5c31af7Sopenharmony_ci } coordTypes[] = 1085e5c31af7Sopenharmony_ci { 1086e5c31af7Sopenharmony_ci { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" }, 1087e5c31af7Sopenharmony_ci { COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform" }, 1088e5c31af7Sopenharmony_ci { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" } 1089e5c31af7Sopenharmony_ci }; 1090e5c31af7Sopenharmony_ci 1091e5c31af7Sopenharmony_ci static const struct 1092e5c31af7Sopenharmony_ci { 1093e5c31af7Sopenharmony_ci const char* name; 1094e5c31af7Sopenharmony_ci deUint32 format; 1095e5c31af7Sopenharmony_ci deUint32 dataType; 1096e5c31af7Sopenharmony_ci } formats[] = 1097e5c31af7Sopenharmony_ci { 1098e5c31af7Sopenharmony_ci { "a8", GL_ALPHA, GL_UNSIGNED_BYTE }, 1099e5c31af7Sopenharmony_ci { "l8", GL_LUMINANCE, GL_UNSIGNED_BYTE }, 1100e5c31af7Sopenharmony_ci { "la88", GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE }, 1101e5c31af7Sopenharmony_ci { "rgb565", GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }, 1102e5c31af7Sopenharmony_ci { "rgb888", GL_RGB, GL_UNSIGNED_BYTE }, 1103e5c31af7Sopenharmony_ci { "rgba4444", GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 }, 1104e5c31af7Sopenharmony_ci { "rgba5551", GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, 1105e5c31af7Sopenharmony_ci { "rgba8888", GL_RGBA, GL_UNSIGNED_BYTE } 1106e5c31af7Sopenharmony_ci }; 1107e5c31af7Sopenharmony_ci 1108e5c31af7Sopenharmony_ci static const struct 1109e5c31af7Sopenharmony_ci { 1110e5c31af7Sopenharmony_ci const char* name; 1111e5c31af7Sopenharmony_ci deUint32 hint; 1112e5c31af7Sopenharmony_ci } genHints[] = 1113e5c31af7Sopenharmony_ci { 1114e5c31af7Sopenharmony_ci { "fastest", GL_FASTEST }, 1115e5c31af7Sopenharmony_ci { "nicest", GL_NICEST } 1116e5c31af7Sopenharmony_ci }; 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_ci static const struct 1119e5c31af7Sopenharmony_ci { 1120e5c31af7Sopenharmony_ci const char* name; 1121e5c31af7Sopenharmony_ci int width; 1122e5c31af7Sopenharmony_ci int height; 1123e5c31af7Sopenharmony_ci } tex2DSizes[] = 1124e5c31af7Sopenharmony_ci { 1125e5c31af7Sopenharmony_ci { DE_NULL, 64, 64 }, // Default. 1126e5c31af7Sopenharmony_ci { "non_square", 32, 64 } 1127e5c31af7Sopenharmony_ci }; 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci // 2D cases. 1130e5c31af7Sopenharmony_ci for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++) 1131e5c31af7Sopenharmony_ci { 1132e5c31af7Sopenharmony_ci tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc); 1133e5c31af7Sopenharmony_ci group2D->addChild(coordTypeGroup); 1134e5c31af7Sopenharmony_ci 1135e5c31af7Sopenharmony_ci for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1136e5c31af7Sopenharmony_ci { 1137e5c31af7Sopenharmony_ci for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++) 1138e5c31af7Sopenharmony_ci { 1139e5c31af7Sopenharmony_ci // Add non_square variants to basic cases only. 1140e5c31af7Sopenharmony_ci int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1; 1141e5c31af7Sopenharmony_ci 1142e5c31af7Sopenharmony_ci for (int size = 0; size < sizeEnd; size++) 1143e5c31af7Sopenharmony_ci { 1144e5c31af7Sopenharmony_ci std::ostringstream name; 1145e5c31af7Sopenharmony_ci name << minFilterModes[minFilter].name 1146e5c31af7Sopenharmony_ci << "_" << wrapModes[wrapMode].name; 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci if (tex2DSizes[size].name) 1149e5c31af7Sopenharmony_ci name << "_" << tex2DSizes[size].name; 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci coordTypeGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), 1152e5c31af7Sopenharmony_ci name.str().c_str(), "", 1153e5c31af7Sopenharmony_ci coordTypes[coordType].type, 1154e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1155e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1156e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1157e5c31af7Sopenharmony_ci GL_RGBA, GL_UNSIGNED_BYTE, 1158e5c31af7Sopenharmony_ci tex2DSizes[size].width, tex2DSizes[size].height)); 1159e5c31af7Sopenharmony_ci } 1160e5c31af7Sopenharmony_ci } 1161e5c31af7Sopenharmony_ci } 1162e5c31af7Sopenharmony_ci } 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ci // 2D bias variants. 1165e5c31af7Sopenharmony_ci { 1166e5c31af7Sopenharmony_ci tcu::TestCaseGroup* biasGroup = new tcu::TestCaseGroup(m_testCtx, "bias", "User-supplied bias value"); 1167e5c31af7Sopenharmony_ci group2D->addChild(biasGroup); 1168e5c31af7Sopenharmony_ci 1169e5c31af7Sopenharmony_ci for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1170e5c31af7Sopenharmony_ci biasGroup->addChild(new Texture2DMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), 1171e5c31af7Sopenharmony_ci minFilterModes[minFilter].name, "", 1172e5c31af7Sopenharmony_ci COORDTYPE_BASIC_BIAS, 1173e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1174e5c31af7Sopenharmony_ci GL_REPEAT, GL_REPEAT, 1175e5c31af7Sopenharmony_ci GL_RGBA, GL_UNSIGNED_BYTE, 1176e5c31af7Sopenharmony_ci tex2DSizes[0].width, tex2DSizes[0].height)); 1177e5c31af7Sopenharmony_ci } 1178e5c31af7Sopenharmony_ci 1179e5c31af7Sopenharmony_ci // 2D mipmap generation variants. 1180e5c31af7Sopenharmony_ci { 1181e5c31af7Sopenharmony_ci tcu::TestCaseGroup* genMipmapGroup = new tcu::TestCaseGroup(m_testCtx, "generate", "Mipmap generation tests"); 1182e5c31af7Sopenharmony_ci group2D->addChild(genMipmapGroup); 1183e5c31af7Sopenharmony_ci 1184e5c31af7Sopenharmony_ci for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); format++) 1185e5c31af7Sopenharmony_ci { 1186e5c31af7Sopenharmony_ci for (int size = 0; size < DE_LENGTH_OF_ARRAY(tex2DSizes); size++) 1187e5c31af7Sopenharmony_ci { 1188e5c31af7Sopenharmony_ci for (int hint = 0; hint < DE_LENGTH_OF_ARRAY(genHints); hint++) 1189e5c31af7Sopenharmony_ci { 1190e5c31af7Sopenharmony_ci std::ostringstream name; 1191e5c31af7Sopenharmony_ci name << formats[format].name; 1192e5c31af7Sopenharmony_ci 1193e5c31af7Sopenharmony_ci if (tex2DSizes[size].name) 1194e5c31af7Sopenharmony_ci name << "_" << tex2DSizes[size].name; 1195e5c31af7Sopenharmony_ci 1196e5c31af7Sopenharmony_ci name << "_" << genHints[hint].name; 1197e5c31af7Sopenharmony_ci 1198e5c31af7Sopenharmony_ci genMipmapGroup->addChild(new Texture2DGenMipmapCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "", 1199e5c31af7Sopenharmony_ci formats[format].format, formats[format].dataType, genHints[hint].hint, 1200e5c31af7Sopenharmony_ci tex2DSizes[size].width, tex2DSizes[size].height)); 1201e5c31af7Sopenharmony_ci } 1202e5c31af7Sopenharmony_ci } 1203e5c31af7Sopenharmony_ci } 1204e5c31af7Sopenharmony_ci } 1205e5c31af7Sopenharmony_ci 1206e5c31af7Sopenharmony_ci const int cubeMapSize = 64; 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_ci static const struct 1209e5c31af7Sopenharmony_ci { 1210e5c31af7Sopenharmony_ci CoordType type; 1211e5c31af7Sopenharmony_ci const char* name; 1212e5c31af7Sopenharmony_ci const char* desc; 1213e5c31af7Sopenharmony_ci } cubeCoordTypes[] = 1214e5c31af7Sopenharmony_ci { 1215e5c31af7Sopenharmony_ci { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" }, 1216e5c31af7Sopenharmony_ci { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }, 1217e5c31af7Sopenharmony_ci { COORDTYPE_BASIC_BIAS, "bias", "User-supplied bias value" } 1218e5c31af7Sopenharmony_ci }; 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci // Cubemap cases. 1221e5c31af7Sopenharmony_ci for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++) 1222e5c31af7Sopenharmony_ci { 1223e5c31af7Sopenharmony_ci tcu::TestCaseGroup* coordTypeGroup = new tcu::TestCaseGroup(m_testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc); 1224e5c31af7Sopenharmony_ci groupCube->addChild(coordTypeGroup); 1225e5c31af7Sopenharmony_ci 1226e5c31af7Sopenharmony_ci for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1227e5c31af7Sopenharmony_ci { 1228e5c31af7Sopenharmony_ci coordTypeGroup->addChild(new TextureCubeMipmapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), 1229e5c31af7Sopenharmony_ci minFilterModes[minFilter].name, "", 1230e5c31af7Sopenharmony_ci cubeCoordTypes[coordType].type, 1231e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1232e5c31af7Sopenharmony_ci GL_CLAMP_TO_EDGE, 1233e5c31af7Sopenharmony_ci GL_CLAMP_TO_EDGE, 1234e5c31af7Sopenharmony_ci GL_RGBA, GL_UNSIGNED_BYTE, cubeMapSize)); 1235e5c31af7Sopenharmony_ci } 1236e5c31af7Sopenharmony_ci } 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci // Cubemap mipmap generation variants. 1239e5c31af7Sopenharmony_ci { 1240e5c31af7Sopenharmony_ci tcu::TestCaseGroup* genMipmapGroup = new tcu::TestCaseGroup(m_testCtx, "generate", "Mipmap generation tests"); 1241e5c31af7Sopenharmony_ci groupCube->addChild(genMipmapGroup); 1242e5c31af7Sopenharmony_ci 1243e5c31af7Sopenharmony_ci for (int format = 0; format < DE_LENGTH_OF_ARRAY(formats); format++) 1244e5c31af7Sopenharmony_ci { 1245e5c31af7Sopenharmony_ci for (int hint = 0; hint < DE_LENGTH_OF_ARRAY(genHints); hint++) 1246e5c31af7Sopenharmony_ci { 1247e5c31af7Sopenharmony_ci std::ostringstream name; 1248e5c31af7Sopenharmony_ci name << formats[format].name 1249e5c31af7Sopenharmony_ci << "_" << genHints[hint].name; 1250e5c31af7Sopenharmony_ci 1251e5c31af7Sopenharmony_ci genMipmapGroup->addChild(new TextureCubeGenMipmapCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "", formats[format].format, formats[format].dataType, genHints[hint].hint, cubeMapSize)); 1252e5c31af7Sopenharmony_ci } 1253e5c31af7Sopenharmony_ci } 1254e5c31af7Sopenharmony_ci } 1255e5c31af7Sopenharmony_ci} 1256e5c31af7Sopenharmony_ci 1257e5c31af7Sopenharmony_ci} // Functional 1258e5c31af7Sopenharmony_ci} // gles2 1259e5c31af7Sopenharmony_ci} // deqp 1260