/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Mipmapping accuracy tests.
 *//*--------------------------------------------------------------------*/

#include "es2aTextureMipmapTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTexVerifierUtil.hpp"
#include "tcuVector.hpp"
#include "tcuMatrix.hpp"
#include "tcuMatrixUtil.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

namespace deqp
{
namespace gles2
{
namespace Accuracy
{

using std::string;
using std::vector;
using tcu::IVec2;
using tcu::IVec4;
using tcu::Mat2;
using tcu::Sampler;
using tcu::TestLog;
using tcu::Vec2;
using tcu::Vec4;
using namespace glu;
using namespace gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

enum CoordType
{
    COORDTYPE_BASIC,      //!< texCoord = translateScale(position).
    COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values.
    COORDTYPE_AFFINE,     //!< texCoord = translateScaleRotateShear(position).
    COORDTYPE_PROJECTED,  //!< Projected coordinates, w != 1

    COORDTYPE_LAST
};

// Texture2DMipmapCase

class Texture2DMipmapCase : public tcu::TestCase
{
public:
    Texture2DMipmapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &renderCtxInfo,
                        const char *name, const char *desc, CoordType coordType, uint32_t minFilter, uint32_t wrapS,
                        uint32_t wrapT, uint32_t format, uint32_t dataType, int width, int height);
    ~Texture2DMipmapCase(void);

    void init(void);
    void deinit(void);
    IterateResult iterate(void);

private:
    Texture2DMipmapCase(const Texture2DMipmapCase &other);
    Texture2DMipmapCase &operator=(const Texture2DMipmapCase &other);

    glu::RenderContext &m_renderCtx;
    const glu::ContextInfo &m_renderCtxInfo;

    CoordType m_coordType;
    uint32_t m_minFilter;
    uint32_t m_wrapS;
    uint32_t m_wrapT;
    uint32_t m_format;
    uint32_t m_dataType;
    int m_width;
    int m_height;

    glu::Texture2D *m_texture;
    TextureRenderer m_renderer;
};

Texture2DMipmapCase::Texture2DMipmapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
                                         const glu::ContextInfo &renderCtxInfo, const char *name, const char *desc,
                                         CoordType coordType, uint32_t minFilter, uint32_t wrapS, uint32_t wrapT,
                                         uint32_t format, uint32_t dataType, int width, int height)
    : TestCase(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
    , m_renderCtx(renderCtx)
    , m_renderCtxInfo(renderCtxInfo)
    , m_coordType(coordType)
    , m_minFilter(minFilter)
    , m_wrapS(wrapS)
    , m_wrapT(wrapT)
    , m_format(format)
    , m_dataType(dataType)
    , m_width(width)
    , m_height(height)
    , m_texture(DE_NULL)
    , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES,
                 renderCtxInfo.isFragmentHighPrecisionSupported() ? glu::PRECISION_HIGHP // Use highp if available.
                                                                    :
                                                                    glu::PRECISION_MEDIUMP)
{
}

Texture2DMipmapCase::~Texture2DMipmapCase(void)
{
    deinit();
}

void Texture2DMipmapCase::init(void)
{
    if (!m_renderCtxInfo.isFragmentHighPrecisionSupported())
        m_testCtx.getLog() << TestLog::Message << "Warning: High precision not supported in fragment shaders."
                           << TestLog::EndMessage;

    m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);

    int numLevels = deLog2Floor32(de::max(m_width, m_height)) + 1;

    // Fill texture with colored grid.
    for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    {
        uint32_t step  = 0xff / (numLevels - 1);
        uint32_t inc   = deClamp32(step * levelNdx, 0x00, 0xff);
        uint32_t dec   = 0xff - inc;
        uint32_t rgb   = (inc << 16) | (dec << 8) | 0xff;
        uint32_t color = 0xff000000 | rgb;

        m_texture->getRefTexture().allocLevel(levelNdx);
        tcu::clear(m_texture->getRefTexture().getLevel(levelNdx), tcu::RGBA(color).toVec());
    }
}

void Texture2DMipmapCase::deinit(void)
{
    delete m_texture;
    m_texture = DE_NULL;

    m_renderer.clear();
}

static void getBasicTexCoord2D(std::vector<float> &dst, int cellNdx)
{
    static const struct
    {
        Vec2 bottomLeft;
        Vec2 topRight;
    } s_basicCoords[] = {
        {Vec2(-0.1f, 0.1f), Vec2(0.8f, 1.0f)},     {Vec2(-0.3f, -0.6f), Vec2(0.7f, 0.4f)},
        {Vec2(-0.3f, 0.6f), Vec2(0.7f, -0.9f)},    {Vec2(-0.8f, 0.6f), Vec2(0.7f, -0.9f)},

        {Vec2(-0.5f, -0.5f), Vec2(1.5f, 1.5f)},    {Vec2(1.0f, -1.0f), Vec2(-1.3f, 1.0f)},
        {Vec2(1.2f, -1.0f), Vec2(-1.3f, 1.6f)},    {Vec2(2.2f, -1.1f), Vec2(-1.3f, 0.8f)},

        {Vec2(-1.5f, 1.6f), Vec2(1.7f, -1.4f)},    {Vec2(2.0f, 1.6f), Vec2(2.3f, -1.4f)},
        {Vec2(1.3f, -2.6f), Vec2(-2.7f, 2.9f)},    {Vec2(-0.8f, -6.6f), Vec2(6.0f, -0.9f)},

        {Vec2(-8.0f, 9.0f), Vec2(8.3f, -7.0f)},    {Vec2(-16.0f, 10.0f), Vec2(18.3f, 24.0f)},
        {Vec2(30.2f, 55.0f), Vec2(-24.3f, -1.6f)}, {Vec2(-33.2f, 64.1f), Vec2(32.1f, -64.1f)},
    };

    DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));

    const Vec2 &bottomLeft = s_basicCoords[cellNdx].bottomLeft;
    const Vec2 &topRight   = s_basicCoords[cellNdx].topRight;

    computeQuadTexCoord2D(dst, bottomLeft, topRight);
}

static void getAffineTexCoord2D(std::vector<float> &dst, int cellNdx)
{
    // Use basic coords as base.
    getBasicTexCoord2D(dst, cellNdx);

    // Rotate based on cell index.
    float angle         = 2.0f * DE_PI * ((float)cellNdx / 16.0f);
    tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle);

    // Second and third row are sheared.
    float shearX          = de::inRange(cellNdx, 4, 11) ? (float)(15 - cellNdx) / 16.0f : 0.0f;
    tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));

    tcu::Mat2 transform = rotMatrix * shearMatrix;
    Vec2 p0             = transform * Vec2(dst[0], dst[1]);
    Vec2 p1             = transform * Vec2(dst[2], dst[3]);
    Vec2 p2             = transform * Vec2(dst[4], dst[5]);
    Vec2 p3             = transform * Vec2(dst[6], dst[7]);

    dst[0] = p0.x();
    dst[1] = p0.y();
    dst[2] = p1.x();
    dst[3] = p1.y();
    dst[4] = p2.x();
    dst[5] = p2.y();
    dst[6] = p3.x();
    dst[7] = p3.y();
}

Texture2DMipmapCase::IterateResult Texture2DMipmapCase::iterate(void)
{
    // Constants.
    const uint32_t magFilter = GL_NEAREST;

    const glw::Functions &gl = m_renderCtx.getFunctions();
    TestLog &log             = m_testCtx.getLog();

    const tcu::Texture2D &refTexture = m_texture->getRefTexture();
    const tcu::TextureFormat &texFmt = refTexture.getFormat();
    tcu::TextureFormatInfo fmtInfo   = tcu::getTextureFormatInfo(texFmt);

    int texWidth          = refTexture.getWidth();
    int texHeight         = refTexture.getHeight();
    int defViewportWidth  = texWidth * 4;
    int defViewportHeight = texHeight * 4;

    RandomViewport viewport(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight,
                            deStringHash(getName()));
    ReferenceParams sampleParams(TEXTURETYPE_2D);
    vector<float> texCoord;
    bool isProjected = m_coordType == COORDTYPE_PROJECTED;
    bool useLodBias  = m_coordType == COORDTYPE_BASIC_BIAS;

    tcu::Surface renderedFrame(viewport.width, viewport.height);

    // Accuracy cases test against ideal lod computation.
    tcu::Surface idealFrame(viewport.width, viewport.height);

    // Viewport is divided into 4x4 grid.
    int gridWidth  = 4;
    int gridHeight = 4;
    int cellWidth  = viewport.width / gridWidth;
    int cellHeight = viewport.height / gridHeight;

    // Accuracy measurements are off unless we get the expected viewport size.
    if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
        throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

    // Sampling parameters.
    sampleParams.sampler     = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);
    sampleParams.samplerType = glu::TextureTestUtil::getSamplerType(m_texture->getRefTexture().getFormat());
    sampleParams.colorBias   = fmtInfo.lookupBias;
    sampleParams.colorScale  = fmtInfo.lookupScale;
    sampleParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);

    // Upload texture data.
    m_texture->upload();

    // Use unit 0.
    gl.activeTexture(GL_TEXTURE0);

    // Bind gradient texture and setup sampler parameters.
    gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
    gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
    gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
    gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
    gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);

    GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");

    // Bias values.
    static const float s_bias[] = {1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f};

    // Projection values.
    static const Vec4 s_projections[] = {Vec4(1.2f, 1.0f, 0.7f, 1.0f), Vec4(1.3f, 0.8f, 0.6f, 2.0f),
                                         Vec4(0.8f, 1.0f, 1.7f, 0.6f), Vec4(1.2f, 1.0f, 1.7f, 1.5f)};

    // Render cells.
    for (int gridY = 0; gridY < gridHeight; gridY++)
    {
        for (int gridX = 0; gridX < gridWidth; gridX++)
        {
            int curX    = cellWidth * gridX;
            int curY    = cellHeight * gridY;
            int curW    = gridX + 1 == gridWidth ? (viewport.width - curX) : cellWidth;
            int curH    = gridY + 1 == gridHeight ? (viewport.height - curY) : cellHeight;
            int cellNdx = gridY * gridWidth + gridX;

            // Compute texcoord.
            switch (m_coordType)
            {
            case COORDTYPE_BASIC_BIAS: // Fall-through.
            case COORDTYPE_PROJECTED:
            case COORDTYPE_BASIC:
                getBasicTexCoord2D(texCoord, cellNdx);
                break;
            case COORDTYPE_AFFINE:
                getAffineTexCoord2D(texCoord, cellNdx);
                break;
            default:
                DE_ASSERT(false);
            }

            if (isProjected)
                sampleParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];

            if (useLodBias)
                sampleParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];

            // Render with GL.
            gl.viewport(viewport.x + curX, viewport.y + curY, curW, curH);
            m_renderer.renderQuad(0, &texCoord[0], sampleParams);

            // Render reference(s).
            {
                tcu::SurfaceAccess idealDst(idealFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY,
                                            curW, curH);
                sampleParams.lodMode = LODMODE_EXACT;
                sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], sampleParams);
            }
        }
    }

    // Read result.
    glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

    // Compare and log.
    {
        const int bestScoreDiff  = (texWidth / 16) * (texHeight / 16);
        const int worstScoreDiff = texWidth * texHeight;

        int score = measureAccuracy(log, idealFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
    }

    return STOP;
}

// TextureCubeMipmapCase

class TextureCubeMipmapCase : public tcu::TestCase
{
public:
    TextureCubeMipmapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
                          const glu::ContextInfo &renderCtxInfo, const char *name, const char *desc,
                          CoordType coordType, uint32_t minFilter, uint32_t wrapS, uint32_t wrapT, uint32_t format,
                          uint32_t dataType, int size);
    ~TextureCubeMipmapCase(void);

    void init(void);
    void deinit(void);
    IterateResult iterate(void);

private:
    TextureCubeMipmapCase(const TextureCubeMipmapCase &other);
    TextureCubeMipmapCase &operator=(const TextureCubeMipmapCase &other);

    glu::RenderContext &m_renderCtx;
    const glu::ContextInfo &m_renderCtxInfo;

    CoordType m_coordType;
    uint32_t m_minFilter;
    uint32_t m_wrapS;
    uint32_t m_wrapT;
    uint32_t m_format;
    uint32_t m_dataType;
    int m_size;

    glu::TextureCube *m_texture;
    TextureRenderer m_renderer;
};

TextureCubeMipmapCase::TextureCubeMipmapCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
                                             const glu::ContextInfo &renderCtxInfo, const char *name, const char *desc,
                                             CoordType coordType, uint32_t minFilter, uint32_t wrapS, uint32_t wrapT,
                                             uint32_t format, uint32_t dataType, int size)
    : TestCase(testCtx, tcu::NODETYPE_ACCURACY, name, desc)
    , m_renderCtx(renderCtx)
    , m_renderCtxInfo(renderCtxInfo)
    , m_coordType(coordType)
    , m_minFilter(minFilter)
    , m_wrapS(wrapS)
    , m_wrapT(wrapT)
    , m_format(format)
    , m_dataType(dataType)
    , m_size(size)
    , m_texture(DE_NULL)
    , m_renderer(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES,
                 renderCtxInfo.isFragmentHighPrecisionSupported() ? glu::PRECISION_HIGHP // Use highp if available.
                                                                    :
                                                                    glu::PRECISION_MEDIUMP)
{
}

TextureCubeMipmapCase::~TextureCubeMipmapCase(void)
{
    deinit();
}

void TextureCubeMipmapCase::init(void)
{
    if (!m_renderCtxInfo.isFragmentHighPrecisionSupported())
        m_testCtx.getLog() << TestLog::Message << "Warning: High precision not supported in fragment shaders."
                           << TestLog::EndMessage;

    m_texture = new TextureCube(m_renderCtx, m_format, m_dataType, m_size);

    int numLevels = deLog2Floor32(m_size) + 1;

    // Fill texture with colored grid.
    for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
    {
        for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
        {
            uint32_t step = 0xff / (numLevels - 1);
            uint32_t inc  = deClamp32(step * levelNdx, 0x00, 0xff);
            uint32_t dec  = 0xff - inc;
            uint32_t rgb  = 0;

            switch (faceNdx)
            {
            case 0:
                rgb = (inc << 16) | (dec << 8) | 255;
                break;
            case 1:
                rgb = (255 << 16) | (inc << 8) | dec;
                break;
            case 2:
                rgb = (dec << 16) | (255 << 8) | inc;
                break;
            case 3:
                rgb = (dec << 16) | (inc << 8) | 255;
                break;
            case 4:
                rgb = (255 << 16) | (dec << 8) | inc;
                break;
            case 5:
                rgb = (inc << 16) | (255 << 8) | dec;
                break;
            }

            uint32_t color = 0xff000000 | rgb;

            m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceNdx, levelNdx);
            tcu::clear(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)faceNdx),
                       tcu::RGBA(color).toVec());
        }
    }
}

void TextureCubeMipmapCase::deinit(void)
{
    delete m_texture;
    m_texture = DE_NULL;

    m_renderer.clear();
}

static void randomPartition(vector<IVec4> &dst, de::Random &rnd, int x, int y, int width, int height)
{
    const int minWidth  = 8;
    const int minHeight = 8;

    bool partition  = rnd.getFloat() > 0.4f;
    bool partitionX = partition && width > minWidth && rnd.getBool();
    bool partitionY = partition && height > minHeight && !partitionX;

    if (partitionX)
    {
        int split = width / 2 + rnd.getInt(-width / 4, +width / 4);
        randomPartition(dst, rnd, x, y, split, height);
        randomPartition(dst, rnd, x + split, y, width - split, height);
    }
    else if (partitionY)
    {
        int split = height / 2 + rnd.getInt(-height / 4, +height / 4);
        randomPartition(dst, rnd, x, y, width, split);
        randomPartition(dst, rnd, x, y + split, width, height - split);
    }
    else
        dst.push_back(IVec4(x, y, width, height));
}

static void computeGridLayout(vector<IVec4> &dst, int width, int height)
{
    de::Random rnd(7);
    randomPartition(dst, rnd, 0, 0, width, height);
}

TextureCubeMipmapCase::IterateResult TextureCubeMipmapCase::iterate(void)
{
    // Constants.
    const uint32_t magFilter = GL_NEAREST;

    int texWidth  = m_texture->getRefTexture().getSize();
    int texHeight = m_texture->getRefTexture().getSize();

    int defViewportWidth  = texWidth * 2;
    int defViewportHeight = texHeight * 2;

    const glw::Functions &gl = m_renderCtx.getFunctions();
    TestLog &log             = m_testCtx.getLog();
    RandomViewport viewport(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight,
                            deStringHash(getName()));
    tcu::Sampler sampler = mapGLSampler(m_wrapS, m_wrapT, m_minFilter, magFilter);

    vector<float> texCoord;

    bool isProjected = m_coordType == COORDTYPE_PROJECTED;
    bool useLodBias  = m_coordType == COORDTYPE_BASIC_BIAS;

    tcu::Surface renderedFrame(viewport.width, viewport.height);

    // Accuracy cases test against ideal lod computation.
    tcu::Surface idealFrame(viewport.width, viewport.height);

    // Accuracy measurements are off unless we get the expected viewport size.
    if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
        throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

    // Upload texture data.
    m_texture->upload();

    // Use unit 0.
    gl.activeTexture(GL_TEXTURE0);

    // Bind gradient texture and setup sampler parameters.
    gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
    gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS);
    gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT);
    gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter);
    gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter);

    GLU_EXPECT_NO_ERROR(gl.getError(), "After texture setup");

    // Compute grid.
    vector<IVec4> gridLayout;
    computeGridLayout(gridLayout, viewport.width, viewport.height);

    // Bias values.
    static const float s_bias[] = {1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f};

    // Projection values \note Less agressive than in 2D case due to smaller quads.
    static const Vec4 s_projections[] = {Vec4(1.2f, 1.0f, 0.7f, 1.0f), Vec4(1.3f, 0.8f, 0.6f, 1.1f),
                                         Vec4(0.8f, 1.0f, 1.2f, 0.8f), Vec4(1.2f, 1.0f, 1.3f, 0.9f)};

    for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
    {
        int curX               = gridLayout[cellNdx].x();
        int curY               = gridLayout[cellNdx].y();
        int curW               = gridLayout[cellNdx].z();
        int curH               = gridLayout[cellNdx].w();
        tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
        ReferenceParams params(TEXTURETYPE_CUBE);

        params.sampler = sampler;

        DE_ASSERT(m_coordType != COORDTYPE_AFFINE); // Not supported.
        computeQuadTexCoordCube(texCoord, cubeFace);

        if (isProjected)
        {
            params.flags |= ReferenceParams::PROJECTED;
            params.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
        }

        if (useLodBias)
        {
            params.flags |= ReferenceParams::USE_BIAS;
            params.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
        }

        // Render with GL.
        gl.viewport(viewport.x + curX, viewport.y + curY, curW, curH);
        m_renderer.renderQuad(0, &texCoord[0], params);

        // Render reference(s).
        {
            tcu::SurfaceAccess idealDst(idealFrame, m_renderCtx.getRenderTarget().getPixelFormat(), curX, curY, curW,
                                        curH);
            params.lodMode = LODMODE_EXACT;
            sampleTexture(idealDst, m_texture->getRefTexture(), &texCoord[0], params);
        }
    }

    // Read result.
    glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

    // Compare and log.
    {
        const int bestScoreDiff  = (texWidth / 16) * (texHeight / 16);
        const int worstScoreDiff = texWidth * texHeight;

        int score = measureAccuracy(log, idealFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
    }

    return STOP;
}

TextureMipmapTests::TextureMipmapTests(Context &context) : TestCaseGroup(context, "mipmap", "Mipmapping accuracy tests")
{
}

TextureMipmapTests::~TextureMipmapTests(void)
{
}

void TextureMipmapTests::init(void)
{
    tcu::TestCaseGroup *group2D   = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Mipmapping");
    tcu::TestCaseGroup *groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cube Map Filtering");
    addChild(group2D);
    addChild(groupCube);

    static const struct
    {
        const char *name;
        uint32_t mode;
    } wrapModes[] = {{"clamp", GL_CLAMP_TO_EDGE}, {"repeat", GL_REPEAT}, {"mirror", GL_MIRRORED_REPEAT}};

    static const struct
    {
        const char *name;
        uint32_t mode;
    } minFilterModes[] = {{"nearest_nearest", GL_NEAREST_MIPMAP_NEAREST},
                          {"linear_nearest", GL_LINEAR_MIPMAP_NEAREST},
                          {"nearest_linear", GL_NEAREST_MIPMAP_LINEAR},
                          {"linear_linear", GL_LINEAR_MIPMAP_LINEAR}};

    static const struct
    {
        CoordType type;
        const char *name;
        const char *desc;
    } coordTypes[] = {{COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates"},
                      {COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform"},
                      {COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection"}};

    const int tex2DWidth  = 64;
    const int tex2DHeight = 64;

    // 2D cases.
    for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
    {
        tcu::TestCaseGroup *coordTypeGroup =
            new tcu::TestCaseGroup(m_testCtx, coordTypes[coordType].name, coordTypes[coordType].desc);
        group2D->addChild(coordTypeGroup);

        for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
        {
            for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
            {
                std::ostringstream name;
                name << minFilterModes[minFilter].name << "_" << wrapModes[wrapMode].name;

                coordTypeGroup->addChild(new Texture2DMipmapCase(
                    m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.str().c_str(), "",
                    coordTypes[coordType].type, minFilterModes[minFilter].mode, wrapModes[wrapMode].mode,
                    wrapModes[wrapMode].mode, GL_RGBA, GL_UNSIGNED_BYTE, tex2DWidth, tex2DHeight));
            }
        }
    }

    const int cubeMapSize = 64;

    static const struct
    {
        CoordType type;
        const char *name;
        const char *desc;
    } cubeCoordTypes[] = {{COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates"},
                          {COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection"}};

    // Cubemap cases.
    for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
    {
        tcu::TestCaseGroup *coordTypeGroup =
            new tcu::TestCaseGroup(m_testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc);
        groupCube->addChild(coordTypeGroup);

        for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
        {
            coordTypeGroup->addChild(new TextureCubeMipmapCase(
                m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), minFilterModes[minFilter].name, "",
                cubeCoordTypes[coordType].type, minFilterModes[minFilter].mode, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
                GL_RGBA, GL_UNSIGNED_BYTE, cubeMapSize));
        }
    }
}

} // namespace Accuracy
} // namespace gles2
} // namespace deqp
